c-common.c (c_common_init): Set up CPP arithmetic.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Sun, 5 May 2002 17:05:09 +0000 (17:05 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Sun, 5 May 2002 17:05:09 +0000 (17:05 +0000)
* 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

gcc/ChangeLog
gcc/c-common.c
gcc/cppinit.c
gcc/cpplex.c
gcc/cpplib.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/charconst.c

index b00e90f5a82a9f99b4a8496bc71a9f42edc75626..5fc92e18f9191e4db568706aff51d322ffc5da99 100644 (file)
@@ -1,3 +1,14 @@
+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>
 
        * doc/install.texi (powerpc-*-linux-gnu*): Update build requirements.
index f009cd63a1fc1f011956ce1833ef276c721a0cbb..72c4988b1f3155a99c64e450c2cbaaea4a8722c7 100644 (file)
@@ -4299,6 +4299,14 @@ const char *
 c_common_init (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.  */
   if (flag_preprocess_only)
     {
index 9e7241a4ea313b2e8923cee019a85fd44328acec..974a1ebae85e8b6686bd4fc190fac8bb5c3da937 100644 (file)
@@ -502,14 +502,13 @@ cpp_create_reader (lang)
   CPP_OPTION (pfile, 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))
   CPP_OPTION (pfile, precision) = BITS_PER_HOST_WIDEST_INT;
-#ifndef MAX_CHAR_TYPE_SIZE
-#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-  CPP_OPTION (pfile, char_precision) = MAX_CHAR_TYPE_SIZE;
-  CPP_OPTION (pfile, wchar_precision) = MAX_WCHAR_TYPE_SIZE;
+  CPP_OPTION (pfile, char_precision) = CHAR_BIT;
+  CPP_OPTION (pfile, wchar_precision) = CHAR_BIT * sizeof (int);
+  CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
 
   /* It's simplest to just create this struct whether or not it will
      be needed.  */
@@ -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
    processed.  Setup for processing input from the file named FNAME,
    or stdin if it is the empty string.  Return the original filename
@@ -933,6 +976,8 @@ cpp_read_main_file (pfile, fname, table)
      const char *fname;
      hash_table *table;
 {
+  sanity_checks (pfile);
+
   /* The front ends don't set up the hash table until they have
      finished processing the command line options, so initializing the
      hashtable is deferred until now.  */
@@ -1788,46 +1833,12 @@ cpp_handle_options (pfile, argc, argv)
   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
    cpp_handle_option[s].  Consistency checks etc.  */
 void
 cpp_post_options (pfile)
      cpp_reader *pfile;
 {
-  sanity_checks (pfile);
-
   if (pfile->print_version)
     {
       fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string);
index 51c82b206081fccef0eda57892e06783563cc125..ee34512c73becdacabf824eae97321cc4953842b 100644 (file)
@@ -1883,11 +1883,13 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
   if (token->type == CPP_CHAR)
     {
       width = CPP_OPTION (pfile, char_precision);
+      max_chars = CPP_OPTION (pfile, int_precision) / width;
       unsigned_p = CPP_OPTION (pfile, signed_char) == 0;
     }
   else
     {
       width = CPP_OPTION (pfile, wchar_precision);
+      max_chars = 1;
       unsigned_p = WCHAR_UNSIGNED;
     }
 
@@ -1895,7 +1897,6 @@ cpp_interpret_charconst (pfile, token, warn_multi, pchars_seen, unsignedp)
     mask = ((cppchar_t) 1 << width) - 1;
   else
     mask = ~0;
-  max_chars = BITS_PER_CPPCHAR_T / width;
 
   while (str < limit)
     {
index 72f4884e41999670a39319e4942ffa543fc1fb68..42eae9177e7b94f517bb394f5a2eb9662395bfb8 100644 (file)
@@ -251,9 +251,9 @@ struct cpp_options
   /* -fleading_underscore sets this to "_".  */
   const char *user_label_prefix;
 
-  /* Precision for target CPP arithmetic, target characters and target
-     wide characters, respectively.  */
-  size_t precision, char_precision, wchar_precision;
+  /* Precision for target CPP arithmetic, target characters, target
+     ints and target wide characters, respectively.  */
+  size_t precision, char_precision, int_precision, wchar_precision;
 
   /* The language we're preprocessing.  */
   enum c_lang lang;
index 4a96ac00fa5d05dfb53b80cd4399c337ee6e95aa..29463de55dc434b9ec58f033fface656b174dfe5 100644 (file)
@@ -1,3 +1,7 @@
+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>
 
        * treelang: Added directory for new sample language treelang. Also
index d8a178b7a9f6dcf07d552b5bedf1689b5a0eacd7..07257a74a4ff57bc1b373e6fa037a8f295110191 100644 (file)
 
 void foo ()
 {
-  int c = '';          /* { dg-warning "empty" "empty charconst" } */
-  c = L'';             /* { dg-warning "empty" "empty wide charconst" } */
+  int c;
+  __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 = 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-character" } */
+  c = 'ab';            /* { dg-warning "multi-char" "multi-char" } */
+  /* Wide charconsts cannot contain more than one wide character.  */
+  w = L'ab';           /* { dg-warning "too long" "multi-char wide" } */
 }