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 | |
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
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/c-common.c | 6 | ||||
-rw-r--r-- | gcc/c-common.h | 3 | ||||
-rw-r--r-- | gcc/c-decl.c | 4 | ||||
-rw-r--r-- | gcc/c-lex.c | 2 | ||||
-rw-r--r-- | gcc/c-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 5 | ||||
-rw-r--r-- | gcc/cppexp.c | 11 | ||||
-rw-r--r-- | gcc/cppinit.c | 1 | ||||
-rw-r--r-- | gcc/cpplex.c | 25 | ||||
-rw-r--r-- | gcc/cpplib.h | 9 | ||||
-rw-r--r-- | gcc/doc/cpp.texi | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/charconst-3.c | 16 |
17 files changed, 97 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 00084d7b08d..d88c97359aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk> + + * 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. +doc: + * cpp.texi: Update documentation. + 2002-05-06 Vladimir Makarov <vmakarov@redhat.com> * genautomata.c (form_the_same_automaton_unit_lists_from_regexp): diff --git a/gcc/c-common.c b/gcc/c-common.c index 72c4988b1f3..bc4b0b96d02 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -201,6 +201,10 @@ int flag_short_double; int flag_short_wchar; +/* Nonzero means warn about use of multicharacter literals. */ + +int warn_multichar = 1; + /* Nonzero means warn about possible violations of sequence point rules. */ int warn_sequence_point; @@ -4307,6 +4311,8 @@ c_common_init (filename) options->int_precision = TYPE_PRECISION (integer_type_node); options->wchar_precision = TYPE_PRECISION (wchar_type_node); + options->warn_multichar = warn_multichar; + /* NULL is passed up to toplev.c and we exit quickly. */ if (flag_preprocess_only) { diff --git a/gcc/c-common.h b/gcc/c-common.h index a8439d4966a..eca6cf137f0 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -391,6 +391,9 @@ extern int flag_short_double; extern int flag_short_wchar; +/* Nonzero means warn about use of multicharacter literals. */ +extern int warn_multichar; + /* Warn about *printf or *scanf format/argument anomalies. */ extern int warn_format; diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ae4cebb9d0c..61f8f695e45 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -426,10 +426,6 @@ int warn_sign_compare = -1; int warn_float_equal = 0; -/* Nonzero means warn about use of multicharacter literals. */ - -int warn_multichar = 1; - /* Nonzero means `$' can be in an identifier. */ #ifndef DOLLARS_IN_IDENTIFIERS diff --git a/gcc/c-lex.c b/gcc/c-lex.c index 9679b607f97..075a2edb9ab 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -1359,7 +1359,7 @@ lex_charconst (token) unsigned int chars_seen; int unsignedp; - result = cpp_interpret_charconst (parse_in, token, warn_multichar, + result = cpp_interpret_charconst (parse_in, token, &chars_seen, &unsignedp); /* Cast to cppchar_signed_t to get correct sign-extension of RESULT diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 7225f5d8a50..8ed0b642b90 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -374,10 +374,6 @@ extern int warn_sign_compare; extern int warn_float_equal; -/* Warn about multicharacter constants. */ - -extern int warn_multichar; - /* Nonzero means we are reading code that came from a system header file. */ extern int system_header_p; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 29ced823809..6cd79d76b14 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk> + + * Make-lang.in (decl2.o): Update. + * cp-tree.h (warn_multichar): Remove. + * decl2.c: Include c-common.h. + (warn_multichar): Remove. + 2002-05-03 Jason Merrill <jason@redhat.com> * tree.c (build_cplus_array_type): Only const and volatile get diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 6db4e4c70d0..06052f4f2ba 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -257,7 +257,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \ cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ - output.h except.h toplev.h $(GGC_H) $(RTL_H) + output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \ diagnostic.h cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8be1e6f4e05..db74366e8db 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3111,9 +3111,6 @@ extern int flag_ms_extensions; type signature of any virtual function in the base class. */ extern int warn_overloaded_virtual; -/* Nonzero means warn about use of multicharacter literals. */ -extern int warn_multichar; - /* Set by add_implicitly_declared_members() to keep those members from being flagged as deprecated or reported as using deprecated types. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a904c0dd4bb..f716de0c94e 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA. */ #include "timevar.h" #include "cpplib.h" #include "target.h" +#include "c-common.h" extern cpp_reader *parse_in; /* This structure contains information about the initializations @@ -288,10 +289,6 @@ int warn_old_style_cast; int warn_unknown_pragmas; /* Tri state variable. */ -/* Nonzero means warn about use of multicharacter literals. */ - -int warn_multichar = 1; - /* Nonzero means warn when non-templatized friend functions are declared within a template */ diff --git a/gcc/cppexp.c b/gcc/cppexp.c index b71b02abfd2..288cdd406b0 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -295,7 +295,16 @@ eval_token (pfile, token) case CPP_WCHAR: case CPP_CHAR: - op.value = cpp_interpret_charconst (pfile, token, 1, &temp, &unsignedp); + { + cppchar_t result = cpp_interpret_charconst (pfile, token, + &temp, &unsignedp); + op.value = result; + /* Sign-extend the result if necessary. */ + if (!unsignedp && (cppchar_signed_t) result < 0 + && sizeof (HOST_WIDEST_INT) > sizeof (cppchar_t)) + op.value |= ~(((unsigned HOST_WIDEST_INT) 1 << BITS_PER_CPPCHAR_T) + - 1); + } break; case CPP_NAME: diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 974a1ebae85..1d570b0e98a 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -487,6 +487,7 @@ cpp_create_reader (lang) set_lang (pfile, lang); CPP_OPTION (pfile, warn_import) = 1; + CPP_OPTION (pfile, warn_multichar) = 1; CPP_OPTION (pfile, discard_comments) = 1; CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1; CPP_OPTION (pfile, show_column) = 1; 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; diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 42eae9177e7..ca0eee2bd63 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -196,10 +196,10 @@ struct cpp_token #ifndef MAX_WCHAR_TYPE_SIZE # define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE #endif -#if SIZEOF_INT >= MAX_WCHAR_TYPE_SIZE +#if CHAR_BIT * SIZEOF_INT >= MAX_WCHAR_TYPE_SIZE # define CPPCHAR_SIGNED_T int #else -# if SIZEOF_LONG >= MAX_WCHAR_TYPE_SIZE || !HAVE_LONG_LONG +# if CHAR_BIT * SIZEOF_LONG >= MAX_WCHAR_TYPE_SIZE || !HAVE_LONG_LONG # define CPPCHAR_SIGNED_T long # else # define CPPCHAR_SIGNED_T long long @@ -329,6 +329,9 @@ struct cpp_options /* Nonzero means warn if #import is used. */ unsigned char warn_import; + /* Nonzero means warn about multicharacter charconsts. */ + unsigned char warn_multichar; + /* Nonzero means warn about various incompatibilities with traditional C. */ unsigned char warn_traditional; @@ -558,7 +561,7 @@ extern void _cpp_backup_tokens PARAMS ((cpp_reader *, unsigned int)); /* Evaluate a CPP_CHAR or CPP_WCHAR token. */ extern cppchar_t cpp_interpret_charconst PARAMS ((cpp_reader *, const cpp_token *, - int, unsigned int *, int *)); + unsigned int *, int *)); /* Used to register builtins during the register_builtins callback. The text is the same as the command line argument. */ diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index 7ba498dab5f..0e7d9e878a0 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -3514,19 +3514,17 @@ 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 adding the sign-extended value of the new -character. They have type @code{int}, and are treated as signed -regardless of whether single characters are signed or not. If there -are more characters in the constant than would fit in the target -@code{int}, a diagnostic is given, and the excess leading characters -are ignored. This methodology is not fully compatible with versions -3.1 and earlier of GCC, which used a confusing and inconsistent -valuation technique. +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. For example, 'ab' for a target with an 8-bit @code{char} would be -interpreted as @w{'a' * 256 + 'b'}, and 'a\234' as @w{'a' * 256 + -'\234'}. GCC 3.1 and earlier would give a different value for the -latter example, probably @w{'a' * 256 + (unsigned char) '\234'}. +interpreted as @w{(int) ((unsigned char) 'a' * 256 + (unsigned char) +'b')}, and 'a\234' as @w{(int) ((unsigned char) 'a' * 256 + (unsigned +char) '\234')}. @item Source file inclusion. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ab68f45217b..1b8bd7157c5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk> + + * gcc.dg/cpp/charconst-3.c: Correct tests accordingly. + 2002-05-06 Neil Booth <neil@daikokuya.demon.co.uk> * gcc.dg/cpp/charconst-3.c: Run, don't compile. diff --git a/gcc/testsuite/gcc.dg/cpp/charconst-3.c b/gcc/testsuite/gcc.dg/cpp/charconst-3.c index 2b62400eb45..9d7d2399812 100644 --- a/gcc/testsuite/gcc.dg/cpp/charconst-3.c +++ b/gcc/testsuite/gcc.dg/cpp/charconst-3.c @@ -15,23 +15,31 @@ int main () #if INT_MAX > 127 int scale = (int) (unsigned char) -1 + 1; - if ('ab' != ('a' * scale + 'b')) + if ('ab' != (int) ((unsigned char) 'a' * scale + (unsigned char) 'b')) abort (); - if ('\234b' != ('\234' * scale + 'b')) + if ('\234b' != (int) ((unsigned char) '\234' * scale + (unsigned char) 'b')) abort (); - if ('b\234' != ('b' * scale + '\234')) + if ('b\234' != (int) ((unsigned char) 'b' * scale + (unsigned char) '\234')) abort (); - /* Multichar charconsts have type int and should be signed. */ #if INT_MAX == 32767 +# if '\234a' > 0 +# error Preprocessor charconsts 1 +# endif if ('\234a' > 0) abort (); #elif INT_MAX == 2147483647 +# if '\234aaa' > 0 +# error Preprocessor charconsts 2 +# endif if ('\234aaa' > 0) abort (); #elif INT_MAX == 9223372036854775807 +# if '\234aaaaaaa' > 0 +# error Preprocessor charconsts 3 +# endif if ('\234aaaaaaa' > 0) abort (); #endif |