Commit 2443d4e1 by Neil Booth Committed by Neil Booth

c-common.c (c_common_init): Set up CPP arithmetic.

	* c-common.c (c_common_init): Set up CPP arithmetic.
	* cppinit.c (cpp_create_reader): Default CPP arithmetic to
	something reasonable for the host.
	(sanity_checks): Add checks.
	(cpp_read_main_file): Call sanity_checks() from here...
	(cpp_post_options): ... not here.
	* cpplex.c (cpp_interpret_charconst): Get max_chars right.
	* cpplib.h (struct cpp_options): New member int_precision.
testsuite:
	* gcc.dg/cpp/charconst.c: Update tests.

From-SVN: r53186
parent 791a949f
2002-05-05 Neil Booth <neil@daikokuya.demon.co.uk>
* c-common.c (c_common_init): Set up CPP arithmetic.
* cppinit.c (cpp_create_reader): Default CPP arithmetic to
something reasonable for the host.
(sanity_checks): Add checks.
(cpp_read_main_file): Call sanity_checks() from here...
(cpp_post_options): ... not here.
* cpplex.c (cpp_interpret_charconst): Get max_chars right.
* cpplib.h (struct cpp_options): New member int_precision.
2002-05-05 Franz Sirl <Franz.Sirl-kernel@lauterbach.com> 2002-05-05 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* doc/install.texi (powerpc-*-linux-gnu*): Update build requirements. * doc/install.texi (powerpc-*-linux-gnu*): Update build requirements.
......
...@@ -4299,6 +4299,14 @@ const char * ...@@ -4299,6 +4299,14 @@ const char *
c_common_init (filename) c_common_init (filename)
const char *filename; const char *filename;
{ {
cpp_options *options = cpp_get_options (parse_in);
/* Set up preprocessor arithmetic. Must be done after call to
c_common_nodes_and_builtins for wchar_type_node to be good. */
options->char_precision = TYPE_PRECISION (char_type_node);
options->int_precision = TYPE_PRECISION (integer_type_node);
options->wchar_precision = TYPE_PRECISION (wchar_type_node);
/* NULL is passed up to toplev.c and we exit quickly. */ /* NULL is passed up to toplev.c and we exit quickly. */
if (flag_preprocess_only) if (flag_preprocess_only)
{ {
......
...@@ -502,14 +502,13 @@ cpp_create_reader (lang) ...@@ -502,14 +502,13 @@ cpp_create_reader (lang)
CPP_OPTION (pfile, pending) = CPP_OPTION (pfile, pending) =
(struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending)); (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
/* CPP arithmetic done to existing rules for now. */ /* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
#define BITS_PER_HOST_WIDEST_INT (CHAR_BIT * sizeof (HOST_WIDEST_INT)) #define BITS_PER_HOST_WIDEST_INT (CHAR_BIT * sizeof (HOST_WIDEST_INT))
CPP_OPTION (pfile, precision) = BITS_PER_HOST_WIDEST_INT; CPP_OPTION (pfile, precision) = BITS_PER_HOST_WIDEST_INT;
#ifndef MAX_CHAR_TYPE_SIZE CPP_OPTION (pfile, char_precision) = CHAR_BIT;
#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int);
#endif CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
CPP_OPTION (pfile, char_precision) = MAX_CHAR_TYPE_SIZE;
CPP_OPTION (pfile, wchar_precision) = MAX_WCHAR_TYPE_SIZE;
/* It's simplest to just create this struct whether or not it will /* It's simplest to just create this struct whether or not it will
be needed. */ be needed. */
...@@ -923,6 +922,50 @@ free_chain (head) ...@@ -923,6 +922,50 @@ free_chain (head)
} }
} }
/* Sanity-checks are dependent on command-line options, so it is
called as a subroutine of cpp_read_main_file (). */
#if ENABLE_CHECKING
static void sanity_checks PARAMS ((cpp_reader *));
static void sanity_checks (pfile)
cpp_reader *pfile;
{
cppchar_t test = 0;
/* Sanity checks for assumptions about CPP arithmetic and target
type precisions made by cpplib. */
test--;
if (test < 1)
cpp_error (pfile, DL_FATAL, "cppchar_t must be an unsigned type");
if (CPP_OPTION (pfile, precision) > BITS_PER_HOST_WIDEST_INT)
cpp_error (pfile, DL_FATAL,
"preprocessor arithmetic has maximum precision of %u bits; target requires %u bits",
BITS_PER_HOST_WIDEST_INT, CPP_OPTION (pfile, precision));
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
cpp_error (pfile, DL_FATAL,
"CPP arithmetic must be at least as precise as a target int");
if (CPP_OPTION (pfile, char_precision) < 8)
cpp_error (pfile, DL_FATAL, "target char is less than 8 bits wide");
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
cpp_error (pfile, DL_FATAL,
"target wchar_t is narrower than target char");
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
cpp_error (pfile, DL_FATAL,
"target int is narrower than target char");
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
cpp_error (pfile, DL_FATAL,
"CPP on this host cannot handle wide character constants over %u bits, but the target requires %u bits",
BITS_PER_CPPCHAR_T, CPP_OPTION (pfile, wchar_precision));
}
#else
# define sanity_checks(PFILE)
#endif
/* This is called after options have been parsed, and partially /* This is called after options have been parsed, and partially
processed. Setup for processing input from the file named FNAME, processed. Setup for processing input from the file named FNAME,
or stdin if it is the empty string. Return the original filename or stdin if it is the empty string. Return the original filename
...@@ -933,6 +976,8 @@ cpp_read_main_file (pfile, fname, table) ...@@ -933,6 +976,8 @@ cpp_read_main_file (pfile, fname, table)
const char *fname; const char *fname;
hash_table *table; hash_table *table;
{ {
sanity_checks (pfile);
/* The front ends don't set up the hash table until they have /* The front ends don't set up the hash table until they have
finished processing the command line options, so initializing the finished processing the command line options, so initializing the
hashtable is deferred until now. */ hashtable is deferred until now. */
...@@ -1788,46 +1833,12 @@ cpp_handle_options (pfile, argc, argv) ...@@ -1788,46 +1833,12 @@ cpp_handle_options (pfile, argc, argv)
return i; return i;
} }
/* Sanity-checks are dependent on command-line options, so it is
called as a subroutine of cpp_post_options (). */
#if ENABLE_CHECKING
static void sanity_checks PARAMS ((cpp_reader *));
static void sanity_checks (pfile)
cpp_reader *pfile;
{
cppchar_t test = 0;
size_t max_prec;
/* Sanity checks for CPP arithmetic. */
test--;
if (test < 1)
cpp_error (pfile, DL_FATAL, "cppchar_t must be an unsigned type");
if (CPP_OPTION (pfile, precision) > BITS_PER_HOST_WIDEST_INT)
cpp_error (pfile, DL_FATAL,
"preprocessor arithmetic has maximum precision of %u bits; target requires %u bits",
BITS_PER_HOST_WIDEST_INT, CPP_OPTION (pfile, precision));
max_prec = CPP_OPTION (pfile, char_precision);
if (max_prec < CPP_OPTION (pfile, wchar_precision))
max_prec = CPP_OPTION (pfile, wchar_precision);
if (max_prec > BITS_PER_CPPCHAR_T)
cpp_error (pfile, DL_FATAL,
"CPP on this host cannot handle (wide) character constants over %u bits, but the target requires %u bits",
BITS_PER_CPPCHAR_T, max_prec);
}
#else
# define sanity_checks(PFILE)
#endif
/* Extra processing when all options are parsed, after all calls to /* Extra processing when all options are parsed, after all calls to
cpp_handle_option[s]. Consistency checks etc. */ cpp_handle_option[s]. Consistency checks etc. */
void void
cpp_post_options (pfile) cpp_post_options (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
sanity_checks (pfile);
if (pfile->print_version) if (pfile->print_version)
{ {
fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string); fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string);
......
...@@ -1883,11 +1883,13 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) ...@@ -1883,11 +1883,13 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
if (token->type == CPP_CHAR) if (token->type == CPP_CHAR)
{ {
width = CPP_OPTION (pfile, char_precision); width = CPP_OPTION (pfile, char_precision);
max_chars = CPP_OPTION (pfile, int_precision) / width;
unsigned_p = CPP_OPTION (pfile, signed_char) == 0; unsigned_p = CPP_OPTION (pfile, signed_char) == 0;
} }
else else
{ {
width = CPP_OPTION (pfile, wchar_precision); width = CPP_OPTION (pfile, wchar_precision);
max_chars = 1;
unsigned_p = WCHAR_UNSIGNED; unsigned_p = WCHAR_UNSIGNED;
} }
...@@ -1895,7 +1897,6 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp) ...@@ -1895,7 +1897,6 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
mask = ((cppchar_t) 1 << width) - 1; mask = ((cppchar_t) 1 << width) - 1;
else else
mask = ~0; mask = ~0;
max_chars = BITS_PER_CPPCHAR_T / width;
while (str < limit) while (str < limit)
{ {
......
...@@ -251,9 +251,9 @@ struct cpp_options ...@@ -251,9 +251,9 @@ struct cpp_options
/* -fleading_underscore sets this to "_". */ /* -fleading_underscore sets this to "_". */
const char *user_label_prefix; const char *user_label_prefix;
/* Precision for target CPP arithmetic, target characters and target /* Precision for target CPP arithmetic, target characters, target
wide characters, respectively. */ ints and target wide characters, respectively. */
size_t precision, char_precision, wchar_precision; size_t precision, char_precision, int_precision, wchar_precision;
/* The language we're preprocessing. */ /* The language we're preprocessing. */
enum c_lang lang; enum c_lang lang;
......
2002-05-05 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/charconst.c: Update tests.
2002-05-05 Tim Josling <tej@melbpc.org.au> 2002-05-05 Tim Josling <tej@melbpc.org.au>
* treelang: Added directory for new sample language treelang. Also * treelang: Added directory for new sample language treelang. Also
......
...@@ -21,13 +21,16 @@ ...@@ -21,13 +21,16 @@
void foo () void foo ()
{ {
int c = ''; /* { dg-warning "empty" "empty charconst" } */ int c;
c = L''; /* { dg-warning "empty" "empty wide charconst" } */ __WCHAR_TYPE__ w;
c = ''; /* { dg-warning "empty" "empty charconst" } */
w = L''; /* { dg-warning "empty" "empty wide charconst" } */
c = 'very long'; /* { dg-warning "too long" "long charconst" } */ c = 'very long'; /* { dg-warning "too long" "long charconst" } */
c = L'very long'; /* { dg-warning "too long" "long wide charconst" } */ w = L'very long'; /* { dg-warning "too long" "long wide charconst" } */
/* Don't do this test for L'ab'; it depends upon sizeof (wchar_t). */ c = 'ab'; /* { dg-warning "multi-char" "multi-char" } */
c = 'ab'; /* { dg-warning "multi-char" "multi-character" } */ /* Wide charconsts cannot contain more than one wide character. */
w = L'ab'; /* { dg-warning "too long" "multi-char wide" } */
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment