(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
+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):
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;
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)
{
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;
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
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
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;
+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
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 \
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. */
#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
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 */
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:
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;
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;
{
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;
}
{
/* 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;
#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
/* 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;
/* 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. */
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.
+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.
#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