summaryrefslogtreecommitdiff
path: root/gcc/cpplex.c
diff options
context:
space:
mode:
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-06 22:53:10 +0000
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2002-05-06 22:53:10 +0000
commit318fdd81915678cdc4e744ad9aa51cbfef2b9fc1 (patch)
tree3f56b583072218fe62c5e65ab9af8fa0eb09165a /gcc/cpplex.c
parent09b8097e4cafe3e8cd0e44f136056fce86ccad74 (diff)
downloadgcc-318fdd81915678cdc4e744ad9aa51cbfef2b9fc1.tar.gz
* c-common.c (warn_multichar): New.
(c_common_init): Set CPP's warn_multichar. * c-common.h (warn_multichar): New. * c-decl.c (warn_multichar): Remove. * c-lex.c (lex_charconst): Update. * c-tree.h (warn_multichar): Remove. * cppexp.c (eval_token): Sign-extend charconst value. * cppinit.c (cpp_create_reader): Set warn_multichar. * cpplex.c (cpp_interpret_charconst): Don't sign-extend each character. Update prototype. Sign-extend the result. * cpplib.h: Fix conditions. (struct cpp_options): Add new warning flag. (cpp_interpret_charconst): Update prototype. cp: * Make-lang.in (decl2.o): Update. * cp-tree.h (warn_multichar): Remove. * decl2.c: Include c-common.h. (warn_multichar): Remove. doc: * cpp.texi: Update documentation. testsuite: * gcc.dg/cpp/charconst-3.c: Correct tests accordingly. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53240 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cpplex.c')
-rw-r--r--gcc/cpplex.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index d3268985697..a9f14948133 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -1861,10 +1861,9 @@ cpp_parse_escape (pfile, pstr, limit, wide)
characters seen, and UNSIGNEDP to a variable that indicates whether
the result has signed type. */
cppchar_t
-cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
+cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
cpp_reader *pfile;
const cpp_token *token;
- int warn_multi;
unsigned int *pchars_seen;
int *unsignedp;
{
@@ -1930,11 +1929,10 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
chars_seen++;
- /* Sign-extend the character, scale result, and add the two. */
- if (!unsigned_p && (c & (1 << (width - 1))))
- c |= ~mask;
+ /* Truncate the character, scale the result and merge the two. */
+ c &= mask;
if (width < BITS_PER_CPPCHAR_T)
- result = (result << width) + c;
+ result = (result << width) | c;
else
result = c;
}
@@ -1945,16 +1943,29 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
{
/* 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 for its type");
}
- else if (warn_multi)
+ else if (CPP_OPTION (pfile, warn_multichar))
cpp_error (pfile, DL_WARNING, "multi-character character constant");
}
+ /* Sign-extend the constant. */
+ if (!unsigned_p)
+ {
+ 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);
+ }
+
*pchars_seen = chars_seen;
*unsignedp = unsigned_p;
return result;