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:
Neil Booth 2002-05-06 22:53:10 +00:00 committed by Neil Booth
parent d7ee9f9fa7
commit a5a49440f7
17 changed files with 97 additions and 43 deletions

View 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):

View 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)
{

View 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;

View 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

View 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

View 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;

View 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

View 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 \

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

View 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 */

View 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:

View 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;

View 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;

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

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

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

View 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