This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Partial reversion of charconst patch
- From: Neil Booth <neil at daikokuya dot demon dot co dot uk>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 6 May 2002 21:56:44 +0100
- Subject: 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