diff options
author | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-06 22:53:10 +0000 |
---|---|---|
committer | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-05-06 22:53:10 +0000 |
commit | 318fdd81915678cdc4e744ad9aa51cbfef2b9fc1 (patch) | |
tree | 3f56b583072218fe62c5e65ab9af8fa0eb09165a /gcc/cpplex.c | |
parent | 09b8097e4cafe3e8cd0e44f136056fce86ccad74 (diff) | |
download | gcc-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.c | 25 |
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; |