c-common.c (warn_multichar): New.
* 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. From-SVN: r53240
This commit is contained in:
parent
d7ee9f9fa7
commit
a5a49440f7
17 changed files with 97 additions and 43 deletions
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
11
gcc/cppexp.c
11
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:
|
||||
|
|
|
@ -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;
|
||||
|
|
25
gcc/cpplex.c
25
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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue