]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* c-common.c (warn_multichar): New.
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 May 2002 22:53:10 +0000 (22:53 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 6 May 2002 22:53:10 +0000 (22:53 +0000)
(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

17 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-lex.c
gcc/c-tree.h
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cppexp.c
gcc/cppinit.c
gcc/cpplex.c
gcc/cpplib.h
gcc/doc/cpp.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/charconst-3.c

index 00084d7b08d354ab768770bdba9db3aa1c0c5f88..d88c97359aa0a46375e2e53707aa04e72f1406b4 100644 (file)
@@ -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):
index 72c4988b1f3155a99c64e450c2cbaaea4a8722c7..bc4b0b96d023a21c6ae1544382267c322799d38f 100644 (file)
@@ -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)
     {
index a8439d4966a61835f8e9f53bf94df61583a7f3dd..eca6cf137f0fa3c93b07ac425f9ab42d8bdfa2a7 100644 (file)
@@ -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;
index ae4cebb9d0c7db9d33a254eccfa655fc93d22f7b..61f8f695e4539ddc30b6a284dd841d19d99bc35b 100644 (file)
@@ -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
index 9679b607f973a584785eb529dccb1b92597d8a5e..075a2edb9ab93b763ec6d29bae2059ffec0a527d 100644 (file)
@@ -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
index 7225f5d8a50bc454f22c00e9bc84bf28c46e2cc6..8ed0b642b904b0e7e9676a9c492d79aa6b46e7a8 100644 (file)
@@ -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;
index 29ced8238094d13c15e349541f47543c5580ff2b..6cd79d76b14eb5b55bbf32e532387480cf0373b0 100644 (file)
@@ -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
index 6db4e4c70d0e51b729064970762eb290fa4159d3..06052f4f2ba607f2b0605aecf949fb7f5a431a98 100644 (file)
@@ -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 \
index 8be1e6f4e0570aee2b81f4c18dc1e442d21e60ad..db74366e8db97fd32fe9af5a1f686c5a324f8a8e 100644 (file)
@@ -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.  */
index a904c0dd4bb14bdbb9628fe79e886c4d0aa4df4a..f716de0c94e465f7e974582f15a4f9d499774bd6 100644 (file)
@@ -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 */
 
index b71b02abfd2f658c86abe3ba9e36dfb39af089e4..288cdd406b00818690fc7837c9c1ebe67aa22054 100644 (file)
@@ -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:
index 974a1ebae85e8b6686bd4fc190fac8bb5c3da937..1d570b0e98aeca570edcb0c97dcc23f03ae7a994 100644 (file)
@@ -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;
index d3268985697b42bdfe6a94b1ea2f7ca1b81c3829..a9f14948133cd4fbda95f6370e05f075e41df09a 100644 (file)
@@ -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;
index 42eae9177e7b94f517bb394f5a2eb9662395bfb8..ca0eee2bd639dbce1412e43b42744b4c08dfd677 100644 (file)
@@ -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.  */
index 7ba498dab5f649ce25fc9828f4416696695f3d36..0e7d9e878a0c8f2b9dc2bfe307087531cd9165ba 100644 (file)
@@ -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.
 
index ab68f45217b0f0b427ef519522d4b107b8c51fd7..1b8bd7157c5eca75dd3bf7242c1899befa4e3101 100644 (file)
@@ -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.
index 2b62400eb45614ad79618a559e54c04ec9b95ab4..9d7d2399812d21814771dd2600fd5e92be5ad3ee 100644 (file)
@@ -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