This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cpplib: Multichar charconst changes


Neil Booth wrote:-

> Incidentally, looking into this made me think we don't do the right
> thing for multi-character charconsts.  We give them the same signedness
> as target char; I tend to think they should be signed just like their
> "int" type is.  Also, if target char is signed, we calculate their value
> in the most wacky way, since each char's value is not sign-extended
> to int, but kept in the narrow target char and or-ed into the target int.
> Finally, in view of the way we calculate their value (first char is most
> significant), it seems odd to ignore excess trailing chars rather than
> excess leading chars like normal C arithmetic would when overflowing.

This is addressed with the patch below which has bootstrapped and
regtested (apart from what appears to be one of the format-checking
heisen-failures).  It only affects multichar charconsts.  Do you object
to my applying it Zack?

Neil.

	* cpplex.c (cpp_interpret_charconst): Sign-extend each
	character.  Don't ignore excess characters.  Treat
	multicharacter character constants as signed.

Index: cpplex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplex.c,v
retrieving revision 1.201
diff -u -p -r1.201 cpplex.c
--- cpplex.c	5 May 2002 17:05:07 -0000	1.201
+++ cpplex.c	5 May 2002 20:15:13 -0000
@@ -1928,36 +1928,30 @@ cpp_interpret_charconst (pfile, token, w
 	c = MAP_CHARACTER (c);
 #endif
       
-      /* Merge character into result; ignore excess chars.  */
-      if (++chars_seen <= max_chars)
-	{
-	  if (width < BITS_PER_CPPCHAR_T)
-	    result = (result << width) | (c & mask);
-	  else
-	    result = c;
-	}
+      chars_seen++;
+
+      /* Sign-extend the character, scale result, and add the two.  */
+      if (!unsigned_p && (c & (1 << (width - 1))))
+	c |= ~mask;
+      if (width < BITS_PER_CPPCHAR_T)
+	result = (result << width) + c;
+      else
+	result = c;
     }
 
   if (chars_seen == 0)
     cpp_error (pfile, DL_ERROR, "empty character constant");
-  else if (chars_seen > max_chars)
+  else if (chars_seen > 1)
     {
-      chars_seen = max_chars;
-      cpp_error (pfile, DL_WARNING, "character constant too long");
-    }
-  else if (chars_seen > 1 && warn_multi)
-    cpp_error (pfile, DL_WARNING, "multi-character character constant");
-
-  /* If relevant type is signed, sign-extend the constant.  */
-  if (chars_seen)
-    {
-      unsigned int nbits = chars_seen * width;
-
-      mask = (cppchar_t) ~0 >> (BITS_PER_CPPCHAR_T - nbits);
-      if (unsigned_p || ((result >> (nbits - 1)) & 1) == 0)
-	result &= mask;
-      else
-	result |= ~mask;
+      /* Multichar charconsts are of type int and therefore signed.  */
+      unsigned_p = 0;
+      if (chars_seen > max_chars)
+	{
+	  chars_seen = max_chars;
+	  cpp_error (pfile, DL_WARNING, "character constant too long");
+	}
+      else if (warn_multi)
+	cpp_error (pfile, DL_WARNING, "multi-character character constant");
     }
 
   *pchars_seen = chars_seen;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]