]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* cpplex.c (cpp_interpret_charconst): Truncate as well as
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 May 2002 21:02:31 +0000 (21:02 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 May 2002 21:02:31 +0000 (21:02 +0000)
sign-extend.
doc:
* cpp.texi: Clarify multichar charconst valuation.
testsuite:
* gcc.dg/cpp/charconst-4.c: More tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53301 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cpplex.c
gcc/doc/cpp.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/charconst-4.c [new file with mode: 0644]

index c8321e9a642ca3d6be2722794c4a98042511e20e..3b3bede67ab06f2cadeaafcc01c8ae144e356b5b 100644 (file)
@@ -1,3 +1,10 @@
+2002-05-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * cpplex.c (cpp_interpret_charconst): Truncate as well as
+       sign-extend.
+doc:
+       * cpp.texi: Clarify multichar charconst valuation.
+
 2002-05-08  Mark Mitchell  <mark@codesourcery.com>
 
        * doc/invoke.texi: Document -mwindiss option.
index 39afc5905a93bb5ff68ad152015ecce34e2e61f8..bba6f0747304cfd6ad09c06e08b9996b891e7c50 100644 (file)
@@ -1954,16 +1954,18 @@ cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
        cpp_error (pfile, DL_WARNING, "multi-character character constant");
     }
 
-  /* Sign-extend the constant.  */
-  if (!unsigned_p)
+  /* Sign-extend or truncate the constant to cppchar_t.  The value is
+     in WIDTH bits, but for multi-char charconsts it's value is the
+     full target type's width.  */
+  if (chars_seen > 1)
+    width *= max_chars;
+  if (width < BITS_PER_CPPCHAR_T)
     {
-      size_t precision = width;
-
-      if (chars_seen > 1)
-       precision *= max_chars;
-      if (precision < BITS_PER_CPPCHAR_T
-         && (result & ((cppchar_t) 1 << (precision - 1))))
-       result |= ~(((cppchar_t) 1 << precision) - 1);
+      mask = ((cppchar_t) 1 << width) - 1;
+      if (unsigned_p || !(result & (1 << (width - 1))))
+       result &= mask;
+      else
+       result |= ~mask;
     }
 
   *pchars_seen = chars_seen;
index 0e7d9e878a0c8f2b9dc2bfe307087531cd9165ba..194175362a810ccbb9a34b03784a829a7e084a0f 100644 (file)
@@ -3512,19 +3512,21 @@ The preprocessor and compiler interpret character constants in the
 same way; i.e.@: escape sequences such as @samp{\a} are given the
 values they would have on the target machine.
 
-Multi-character character constants are interpreted a character at a
-time, shifting the previous result left by the number of bits per
-target character and or-ing the value of the new character truncated
-to the width of a target character.  They have type @code{int}, and
-are treated as signed regardless of whether single characters are
-signed or not (a slight change from versions 3.1 and earlier of GCC).
-If there are more characters in the constant than would fit in the
-target @code{int} an error is issued.
+The compiler values a multi-character character constant a character
+at a time, shifting the previous value left by the number of bits per
+target character, and then or-ing in the bit-pattern of the new
+character truncated to the width of a target character.  The final
+bit-pattern is given type @code{int}, and is therefore signed,
+regardless of whether single characters are signed or not (a slight
+change from versions 3.1 and earlier of GCC).  If there are more
+characters in the constant than would fit in the target @code{int} the
+compiler issues a warning, and the excess leading characters are
+ignored.
 
 For example, 'ab' for a target with an 8-bit @code{char} would be
 interpreted as @w{(int) ((unsigned char) 'a' * 256 + (unsigned char)
-'b')}, and 'a\234' as @w{(int) ((unsigned char) 'a' * 256 + (unsigned
-char) '\234')}.
+'b')}, and '\234a' as @w{(int) ((unsigned char) '\234' * 256 + (unsigned
+char) 'a')}.
 
 @item Source file inclusion.
 
index c1dc84933570cb96bed67a35266c7dcc39bc68aa..f0b7a1cf4d1eb2d25590c6b006c7b70d12dc9a02 100644 (file)
@@ -1,3 +1,7 @@
+2002-05-08  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * gcc.dg/cpp/charconst-4.c: More tests.
+
 2002-05-08  Mark Mitchell  <mark@codesourcery.com>
 
        PR c/6569
diff --git a/gcc/testsuite/gcc.dg/cpp/charconst-4.c b/gcc/testsuite/gcc.dg/cpp/charconst-4.c
new file mode 100644 (file)
index 0000000..986ea80
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 2001 Free Software Foundation, Inc.  */
+
+/* { dg-do run } */
+/* { dg-options "-Wno-multichar -fsigned-char" } */
+
+/* This tests how overly-long multichar charconsts are truncated, and
+   whether "short" multichar charconsts are incorrectly sign extended
+   (regardless of char signedness).  Preprocessor is used so that we
+   have only one place where the too long warning is generated, so
+   that the test works for all targets.
+
+   Neil Booth, 8 May 2002.  */
+
+#include <limits.h>
+
+#if INT_MAX == 32767
+# define LONG_CHARCONST '!\234a'
+# define SHORT_CHARCONST '\234a'
+# define POS_CHARCONST '\1'
+#elif INT_MAX == 2147483647
+# define LONG_CHARCONST '!\234abc'
+# define SHORT_CHARCONST '\234abc'
+# define POS_CHARCONST '\234a'
+#elif INT_MAX == 9223372036854775807
+# define LONG_CHARCONST '!\234abcdefg'
+# define SHORT_CHARCONST '\234abcdefg'
+# define POS_CHARCONST '\234a'
+#else
+/* Target int size not handled, do something that won't fail.  */
+# define LONG_CHARCONST '\234a'
+# define SHORT_CHARCONST '\234a'
+# define POS_CHARCONST '\1'
+#endif
+
+#if POS_CHARCONST < 0
+# error Charconst incorrectly sign-extended
+#endif
+
+#if LONG_CHARCONST != SHORT_CHARCONST /* { dg-warning "too long" "" } */
+# error Overly long charconst truncates wrongly for preprocessor
+#endif
+
+int main ()
+{
+  if (POS_CHARCONST < 0)
+    abort ();
+  if (LONG_CHARCONST != SHORT_CHARCONST)  /* { dg-warning "too long" "" } */
+    abort ();
+  return 0;
+}