This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Partial reversion of charconst patch


As dicussesed in another thread, the way I was building
multichar charconsts didn't make much sense.

I also noticed a silly mistake in cpplib.h, and that
we weren't doing proper sign-extension, so I've fixed
these issues.  New cpp testcases for sign-extension
forced me to properly implement the equivalent of
warn_multichar in cpplib, so I did that by having
it be a member of cpp_options and letting the
front ends set it.  This required consolidation of
the separate warn_multichar flags in the C++ and C
front ends into c-common.c.

I'm about to apply this, the regtesting is looking good.
It should fix the PowerPC regression too.

Neil.

	* 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.

============================================================
Index: gcc/c-common.c
--- gcc/c-common.c	5 May 2002 17:05:06 -0000	1.317
+++ gcc/c-common.c	6 May 2002 19:23:03 -0000
@@ -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;
@@ -4306,6 +4310,8 @@ c_common_init (filename)
   options->char_precision = TYPE_PRECISION (char_type_node);
   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: gcc/c-common.h
--- gcc/c-common.h	27 Apr 2002 06:53:05 -0000	1.133
+++ gcc/c-common.h	6 May 2002 19:23:06 -0000
@@ -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: gcc/c-decl.c
--- gcc/c-decl.c	3 May 2002 12:09:33 -0000	1.323
+++ gcc/c-decl.c	6 May 2002 19:23:30 -0000
@@ -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: gcc/c-lex.c
--- gcc/c-lex.c	4 May 2002 20:14:58 -0000	1.175
+++ gcc/c-lex.c	6 May 2002 19:23:30 -0000
@@ -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: gcc/c-tree.h
--- gcc/c-tree.h	25 Apr 2002 06:24:22 -0000	1.96
+++ gcc/c-tree.h	6 May 2002 19:23:31 -0000
@@ -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: gcc/cppexp.c
--- gcc/cppexp.c	4 May 2002 07:30:32 -0000	1.112
+++ gcc/cppexp.c	6 May 2002 19:23:32 -0000
@@ -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: gcc/cppinit.c
--- gcc/cppinit.c	5 May 2002 17:05:07 -0000	1.219
+++ gcc/cppinit.c	6 May 2002 19:23:37 -0000
@@ -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: gcc/cpplex.c
--- gcc/cpplex.c	5 May 2002 23:13:04 -0000	1.202
+++ gcc/cpplex.c	6 May 2002 19:23:42 -0000
@@ -1861,10 +1861,9 @@ cpp_parse_escape (pfile, pstr, limit, wi
    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, w
       
       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,14 +1943,25 @@ cpp_interpret_charconst (pfile, token, w
     {
       /* 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 = max_chars * width;
+
+      if (precision < BITS_PER_CPPCHAR_T
+	  && (result & ((cppchar_t) 1 << (precision - 1))))
+	result |= ~(((cppchar_t) 1 << precision) - 1);
     }
 
   *pchars_seen = chars_seen;
============================================================
Index: gcc/cpplib.h
--- gcc/cpplib.h	5 May 2002 17:05:07 -0000	1.214
+++ gcc/cpplib.h	6 May 2002 19:23:45 -0000
@@ -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 ((
 /* 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: gcc/cp/Make-lang.in
--- gcc/cp/Make-lang.in	31 Mar 2002 22:32:03 -0000	1.111
+++ gcc/cp/Make-lang.in	6 May 2002 19:23:46 -0000
@@ -257,7 +257,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) flags
   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: gcc/cp/cp-tree.h
--- gcc/cp/cp-tree.h	25 Apr 2002 18:04:50 -0000	1.711
+++ gcc/cp/cp-tree.h	6 May 2002 19:24:01 -0000
@@ -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: gcc/cp/decl2.c
--- gcc/cp/decl2.c	18 Apr 2002 17:53:56 -0000	1.530
+++ gcc/cp/decl2.c	6 May 2002 19:24:13 -0000
@@ -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
@@ -287,10 +288,6 @@ int warn_old_style_cast;
 /* Warn about #pragma directives that are not recognised.  */      
 
 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: gcc/doc/cpp.texi
--- gcc/doc/cpp.texi	5 May 2002 23:45:06 -0000	1.32
+++ gcc/doc/cpp.texi	6 May 2002 19:24:29 -0000
@@ -3514,19 +3514,17 @@ values they would have on the target mac
 
 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: gcc/testsuite/gcc.dg/cpp/charconst-3.c
--- gcc/testsuite/gcc.dg/cpp/charconst-3.c	6 May 2002 08:34:57 -0000	1.2
+++ gcc/testsuite/gcc.dg/cpp/charconst-3.c	6 May 2002 19:24:29 -0000
@@ -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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]