This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: Multichar charconst changes
- From: Neil Booth <neil at daikokuya dot demon dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org, Zack Weinberg <zack at codesourcery dot com>
- Date: Sun, 5 May 2002 21:34:45 +0100
- Subject: cpplib: Multichar charconst changes
- References: <200205042259.g44MxYG26529@maat.sfbay.redhat.com> <20020505155025.GA24215@daikokuya.demon.co.uk>
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;