OSDN Git Service

2002-05-29 Neil Booth <neil@daikokuya.demon.co.uk>
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 May 2002 17:15:42 +0000 (17:15 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 May 2002 17:15:42 +0000 (17:15 +0000)
    Zack Weinberg <zack@codesourcery.com>

* cppexp.c (cpp_num): Move to cpplib.h.
(CPP_ERROR): Remove.
(interpret_float_suffix, interpret_int_suffix): New.
(struct suffix, vsuf_1, vsuf_2, vsuf_3): Remove.
(cpp_classify_number, cpp_interpret_integer): New.
(interpret_number): Remove.
(eval_token): Update to use new routines.
* cpphash.h (cpp_num_part): Move to cpplib.h.
* cppinit.c (cpp_post_options): Set warn_long_long.
* cpplib.h (struct cpp_options): Add warn_long_long.
(cpp_num, cpp_num_part, CPP_N_CATEGORY, CPP_N_INVALID,
CPP_N_INTEGER, CPP_N_FLOATING, CPP_N_WIDTH, CPP_N_SMALL,
CPP_N_MEDIUM, CPP_N_LARGE, CPP_N_RADIX, CPP_N_DEC, CPP_N_HEX,
CPP_N_OCTAL, CPP_N_UNSIGNED, CPP_N_IMAGINARY, cpp_classify_number,
cpp_interpret_integer): New.
testsuite:
* gcc.dg/cpp/c++98-pedantic.c, gcc.dg/cpp/c89-pedantic.c,
gcc.dg/cpp/c94-pedantic.c, gcc.dg/cpp/gnuc89-pedantic.c,
gcc.dg/cpp/if-1.c: Update for modified diagnostics.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54007 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cppexp.c
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplib.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/c++98-pedantic.c
gcc/testsuite/gcc.dg/cpp/c89-pedantic.c
gcc/testsuite/gcc.dg/cpp/c94-pedantic.c
gcc/testsuite/gcc.dg/cpp/gnuc89-pedantic.c
gcc/testsuite/gcc.dg/cpp/if-1.c

index d4e8fa0..75ebd81 100644 (file)
@@ -1,3 +1,22 @@
+2002-05-29  Neil Booth  <neil@daikokuya.demon.co.uk>
+           Zack Weinberg <zack@codesourcery.com>
+
+       * cppexp.c (cpp_num): Move to cpplib.h.
+       (CPP_ERROR): Remove.
+       (interpret_float_suffix, interpret_int_suffix): New.
+       (struct suffix, vsuf_1, vsuf_2, vsuf_3): Remove.
+       (cpp_classify_number, cpp_interpret_integer): New.
+       (interpret_number): Remove.
+       (eval_token): Update to use new routines.
+       * cpphash.h (cpp_num_part): Move to cpplib.h.
+       * cppinit.c (cpp_post_options): Set warn_long_long.
+       * cpplib.h (struct cpp_options): Add warn_long_long.
+       (cpp_num, cpp_num_part, CPP_N_CATEGORY, CPP_N_INVALID,
+       CPP_N_INTEGER, CPP_N_FLOATING, CPP_N_WIDTH, CPP_N_SMALL,
+       CPP_N_MEDIUM, CPP_N_LARGE, CPP_N_RADIX, CPP_N_DEC, CPP_N_HEX,
+       CPP_N_OCTAL, CPP_N_UNSIGNED, CPP_N_IMAGINARY, cpp_classify_number,
+       cpp_interpret_integer): New.
+
 2002-05-29  Joel Sherrill <joel@OARcorp.com>
 
        * config/rs6000/rs6000.h (ASM_CPU_SPEC): Use -m403 and -m405.
index c76e330..73a892f 100644 (file)
@@ -23,23 +23,11 @@ Boston, MA 02111-1307, USA.  */
 #include "cpplib.h"
 #include "cpphash.h"
 
-typedef struct cpp_num cpp_num;
-
 #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT)
 #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2))
 #define LOW_PART(num_part) (num_part & HALF_MASK)
 #define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2))
 
-/* A preprocessing number.  Code assumes that any unused high bits of
-   the double integer are set to zero.  */
-struct cpp_num
-{
-  cpp_num_part high;
-  cpp_num_part low;
-  bool unsignedp;  /* True if value should be treated as unsigned.  */
-  bool overflow;   /* True if the most recent calculation overflowed.  */
-};
-
 struct op
 {
   cpp_num value;                    /* The value logically "right" of op.  */
@@ -72,15 +60,13 @@ static cpp_num num_lshift PARAMS ((cpp_num, size_t, size_t));
 static cpp_num num_rshift PARAMS ((cpp_num, size_t, size_t));
 
 static cpp_num append_digit PARAMS ((cpp_num, int, int, size_t));
-static cpp_num interpret_number PARAMS ((cpp_reader *, const cpp_token *));
 static cpp_num parse_defined PARAMS ((cpp_reader *));
 static cpp_num eval_token PARAMS ((cpp_reader *, const cpp_token *));
 static struct op *reduce PARAMS ((cpp_reader *, struct op *, enum cpp_ttype));
+static unsigned int interpret_float_suffix PARAMS ((const uchar *, size_t));
+static unsigned int interpret_int_suffix PARAMS ((const uchar *, size_t));
 
-/* Token type abuse.  There is no "error" token, but we can't get
-   comments in #if, so we can abuse that token type.  Similarly,
-   create unary plus and minus operators.  */
-#define CPP_ERROR CPP_COMMENT
+/* Token type abuse to create unary plus and minus operators.  */
 #define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
 #define CPP_UMINUS (CPP_LAST_CPP_OP + 2)
 
@@ -91,28 +77,317 @@ static struct op *reduce PARAMS ((cpp_reader *, struct op *, enum cpp_ttype));
 #define SYNTAX_ERROR2(msgid, arg) \
   do { cpp_error (pfile, DL_ERROR, msgid, arg); goto syntax_error; } while(0)
 
-struct suffix
+/* Subroutine of cpp_classify_number.  S points to a float suffix of
+   length LEN, possibly zero.  Returns 0 for an invalid suffix, or a
+   flag vector describing the suffix.  */
+static unsigned int
+interpret_float_suffix (s, len)
+     const uchar *s;
+     size_t len;
 {
-  const unsigned char s[4];
-  const unsigned char u;
-  const unsigned char l;
-};
+  size_t f = 0, l = 0, i = 0;
 
-static const struct suffix vsuf_1[] = {
-  { "u", 1, 0 }, { "U", 1, 0 },
-  { "l", 0, 1 }, { "L", 0, 1 }
-};
+  while (len--)
+    switch (s[len])
+      {
+      case 'f': case 'F': f++; break;
+      case 'l': case 'L': l++; break;
+      case 'i': case 'I':
+      case 'j': case 'J': i++; break;
+      default:
+       return 0;
+      }
 
-static const struct suffix vsuf_2[] = {
-  { "ul", 1, 1 }, { "UL", 1, 1 }, { "uL", 1, 1 }, { "Ul", 1, 1 },
-  { "lu", 1, 1 }, { "LU", 1, 1 }, { "Lu", 1, 1 }, { "lU", 1, 1 },
-  { "ll", 0, 2 }, { "LL", 0, 2 }
-};
+  if (f + l > 1 || i > 1)
+    return 0;
 
-static const struct suffix vsuf_3[] = {
-  { "ull", 1, 2 }, { "ULL", 1, 2 }, { "uLL", 1, 2 }, { "Ull", 1, 2 },
-  { "llu", 1, 2 }, { "LLU", 1, 2 }, { "LLu", 1, 2 }, { "llU", 1, 2 }
-};
+  return ((i ? CPP_N_IMAGINARY : 0)
+         | (f ? CPP_N_SMALL :
+            l ? CPP_N_LARGE : CPP_N_MEDIUM));
+}
+
+/* Subroutine of cpp_classify_number.  S points to an integer suffix
+   of length LEN, possibly zero. Returns 0 for an invalid suffix, or a
+   flag vector describing the suffix.  */
+static unsigned int
+interpret_int_suffix (s, len)
+     const uchar *s;
+     size_t len;
+{
+  size_t u, l, i;
+
+  u = l = i = 0;
+
+  while (len--)
+    switch (s[len])
+      {
+      case 'u': case 'U':      u++; break;
+      case 'i': case 'I':
+      case 'j': case 'J':      i++; break;
+      case 'l': case 'L':      l++;
+       /* If there are two Ls, they must be adjacent and the same case.  */
+       if (l == 2 && s[len] != s[len + 1])
+         return 0;
+       break;
+      default:
+       return 0;
+      }
+
+  if (l > 2 || u > 1 || i > 1)
+    return 0;
+
+  return ((i ? CPP_N_IMAGINARY : 0)
+         | (u ? CPP_N_UNSIGNED : 0)
+         | ((l == 0) ? CPP_N_SMALL
+            : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
+}
+
+/* Categorize numeric constants according to their field (integer,
+   floating point, or invalid), radix (decimal, octal, hexadecimal),
+   and type suffixes.  */
+unsigned int
+cpp_classify_number (pfile, token)
+     cpp_reader *pfile;
+     const cpp_token *token;
+{
+  const uchar *str = token->val.str.text;
+  const uchar *limit;
+  unsigned int max_digit, result, radix;
+  enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
+
+  /* If the lexer has done its job, length one can only be a single
+     digit.  Fast-path this very common case.  */
+  if (token->val.str.len == 1)
+    return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;
+
+  limit = str + token->val.str.len;
+  float_flag = NOT_FLOAT;
+  max_digit = 0;
+  radix = 10;
+
+  /* First, interpret the radix.  */
+  if (*str == '0')
+    {
+      radix = 8;
+      str++;
+
+      /* Require at least one hex digit to classify it as hex.  */
+      if ((*str == 'x' || *str == 'X') && ISXDIGIT (str[1]))
+       {
+         radix = 16;
+         str++;
+       }
+    }
+
+  /* Now scan for a well-formed integer or float.  */
+  for (;;)
+    {
+      unsigned int c = *str++;
+
+      if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
+       {
+         c = hex_value (c);
+         if (c > max_digit)
+           max_digit = c;
+       }
+      else if (c == '.')
+       {
+         if (float_flag == NOT_FLOAT)
+           float_flag = AFTER_POINT;
+         else
+           SYNTAX_ERROR ("too many decimal points in number");
+       }
+      else if ((radix <= 10 && (c == 'e' || c == 'E'))
+              || (radix == 16 && (c == 'p' || c == 'P')))
+       {
+         float_flag = AFTER_EXPON;
+         break;
+       }
+      else
+       {
+         /* Start of suffix.  */
+         str--;
+         break;
+       }
+    }
+
+  if (float_flag != NOT_FLOAT && radix == 8)
+    radix = 10;
+
+  if (max_digit >= radix)
+    SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
+
+  if (float_flag != NOT_FLOAT)
+    {
+      if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
+       cpp_error (pfile, DL_PEDWARN,
+                  "use of C99 hexadecimal floating constant");
+
+      if (float_flag == AFTER_EXPON)
+       {
+         if (*str == '+' || *str == '-')
+           str++;
+
+         /* Exponent is decimal, even if string is a hex float.  */
+         if (!ISDIGIT (*str))
+           SYNTAX_ERROR ("exponent has no digits");
+
+         do
+           str++;
+         while (ISDIGIT (*str));
+       }
+      else if (radix == 16)
+       SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
+
+      result = interpret_float_suffix (str, limit - str);
+      if (result == 0)
+       {
+         cpp_error (pfile, DL_ERROR,
+                    "invalid suffix \"%.*s\" on floating constant",
+                    limit - str, str);
+         return CPP_N_INVALID;
+       }
+
+      /* Traditional C didn't accept any floating suffixes.  */
+      if (limit != str
+         && CPP_WTRADITIONAL (pfile)
+         && ! cpp_sys_macro_p (pfile))
+       cpp_error (pfile, DL_WARNING,
+                  "traditional C rejects the \"%.*s\" suffix",
+                  limit - str, str);
+
+      result |= CPP_N_FLOATING;
+    }
+  else
+    {
+      result = interpret_int_suffix (str, limit - str);
+      if (result == 0)
+       {
+         cpp_error (pfile, DL_ERROR,
+                    "invalid suffix \"%.*s\" on integer constant",
+                    limit - str, str);
+         return CPP_N_INVALID;
+       }
+
+      /* Traditional C only accepted the 'L' suffix.  */
+      if (result != CPP_N_SMALL && result != CPP_N_MEDIUM
+         && CPP_WTRADITIONAL (pfile)
+         && ! cpp_sys_macro_p (pfile))
+       cpp_error (pfile, DL_WARNING,
+                  "traditional C rejects the \"%.*s\" suffix",
+                  limit - str, str);
+
+      if ((result & CPP_N_WIDTH) == CPP_N_LARGE
+         && ! CPP_OPTION (pfile, c99)
+         && CPP_OPTION (pfile, warn_long_long))
+       cpp_error (pfile, DL_PEDWARN, "use of C99 long long integer constant");
+
+      result |= CPP_N_INTEGER;
+    }
+
+  if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
+    cpp_error (pfile, DL_PEDWARN, "imaginary constants are a GCC extension");
+
+  if (radix == 10)
+    result |= CPP_N_DECIMAL;
+  else if (radix == 16)
+    result |= CPP_N_HEX;
+  else
+    result |= CPP_N_OCTAL;
+
+  return result;
+
+ syntax_error:
+  return CPP_N_INVALID;
+}
+
+/* cpp_interpret_integer converts an integer constant into a cpp_num,
+   of precision options->precision.
+
+   We do not provide any interface for decimal->float conversion,
+   because the preprocessor doesn't need it and the floating point
+   handling in GCC proper is too ugly to speak of.  */
+cpp_num
+cpp_interpret_integer (pfile, token, type)
+     cpp_reader *pfile;
+     const cpp_token *token;
+     unsigned int type;
+{
+  const uchar *p, *end;
+  cpp_num result;
+
+  result.low = 0;
+  result.high = 0;
+  result.unsignedp = type & CPP_N_UNSIGNED;
+  result.overflow = 0;
+
+  p = token->val.str.text;
+  end = p + token->val.str.len;
+
+  /* Common case of a single digit.  */
+  if (token->val.str.len == 1)
+    result.low = p[0] - '0';
+  else
+    {
+      cpp_num_part max;
+      size_t precision = CPP_OPTION (pfile, precision);
+      unsigned int base = 10, c = 0;
+      bool overflow = false;
+
+      if ((type & CPP_N_RADIX) == CPP_N_OCTAL)
+       {
+         base = 8;
+         p++;
+       }
+      else if ((type & CPP_N_RADIX) == CPP_N_HEX)
+       {
+         base = 16;
+         p += 2;
+       }
+
+      /* We can add a digit to numbers strictly less than this without
+        needing the precision and slowness of double integers.  */
+      max = ~(cpp_num_part) 0;
+      if (precision < PART_PRECISION)
+       max >>= PART_PRECISION - precision;
+      max = (max - base + 1) / base + 1;
+
+      for (; p < end; p++)
+       {
+         c = *p;
+
+         if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
+           c = hex_value (c);
+         else
+           break;
+
+         /* Strict inequality for when max is set to zero.  */
+         if (result.low < max)
+           result.low = result.low * base + c;
+         else
+           {
+             result = append_digit (result, c, base, precision);
+             overflow |= result.overflow;
+             max = 0;
+           }
+       }
+
+      if (overflow)
+       cpp_error (pfile, DL_PEDWARN,
+                  "integer constant is too large for its type");
+      else if (!result.unsignedp && !num_positive (result, precision))
+       {
+         /* If too big to be signed, consider it unsigned.  Only warn
+            for decimal numbers.  */
+         if (base == 10)
+           cpp_error (pfile, DL_WARNING,
+                      "integer constant is so large that it is unsigned");
+         result.unsignedp = 1;
+       }
+    }
+
+  return result;
+}
 
 /* Append DIGIT to NUM, a number of PRECISION bits being read in base
    BASE.  */
@@ -167,149 +442,6 @@ append_digit (num, digit, base, precision)
   return result;
 }
 
-/* Parse and convert what is presumably an integer in TOK.  Accepts
-   decimal, hex, or octal with or without size suffixes.  Returned op
-   is CPP_ERROR on error, otherwise it is a CPP_NUMBER.  */
-static cpp_num
-interpret_number (pfile, tok)
-     cpp_reader *pfile;
-     const cpp_token *tok;
-{
-  cpp_num result;
-  cpp_num_part max;
-  const uchar *p = tok->val.str.text;
-  const uchar *end;
-  const struct suffix *sufftab;
-  size_t precision;
-  unsigned int i, nsuff, base, c;
-  bool overflow, big_digit;
-
-  result.low = 0;
-  result.high = 0;
-  result.unsignedp = 0;
-  result.overflow = 0;
-
-  /* Common case of a single digit.  */
-  end = p + tok->val.str.len;
-  if (tok->val.str.len == 1 && (unsigned int) (p[0] - '0') <= 9)
-    {
-      result.low = p[0] - '0';
-      return result;
-    }
-
-  base = 10;
-  if (p[0] == '0')
-    {
-      if (end - p >= 3 && (p[1] == 'x' || p[1] == 'X'))
-       {
-         p += 2;
-         base = 16;
-       }
-      else
-       {
-         p += 1;
-         base = 8;
-       }
-    }
-
-  c = 0;
-  overflow = big_digit = false;
-  precision = CPP_OPTION (pfile, precision);
-
-  /* We can add a digit to numbers less than this without needing
-     double integers.  9 is the maximum digit for octal and decimal;
-     for hex it is annihilated by the division anyway.  */
-  max = ~(cpp_num_part) 0;
-  if (precision < PART_PRECISION)
-    max >>= PART_PRECISION - precision;
-  max = (max - 9) / base + 1;
-
-  for(; p < end; p++)
-    {
-      c = *p;
-
-      if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
-       c = hex_value (c);
-      else
-       break;
-
-      if (c >= base)
-       big_digit = true;
-
-      /* Strict inequality for when max is set to zero.  */
-      if (result.low < max)
-       result.low = result.low * base + c;
-      else
-       {
-         result = append_digit (result, c, base, precision);
-         overflow |= result.overflow;
-         max = 0;
-       }
-    }
-
-  if (p < end)
-    {
-      /* Check for a floating point constant.  Note that float constants
-        with an exponent or suffix but no decimal point are technically
-        invalid (C99 6.4.4.2) but accepted elsewhere.  */
-      if ((c == '.' || c == 'F' || c == 'f')
-         || (base == 10 && (c == 'E' || c == 'e')
-             && p+1 < end && (p[1] == '+' || p[1] == '-'))
-         || (base == 16 && (c == 'P' || c == 'p')
-             && p+1 < end && (p[1] == '+' || p[1] == '-')))
-       SYNTAX_ERROR ("floating point numbers are not valid in #if");
-
-      /* Determine the suffix. l means long, and u means unsigned.
-        See the suffix tables, above.  */
-      switch (end - p)
-       {
-       case 1: sufftab = vsuf_1; nsuff = ARRAY_SIZE (vsuf_1); break;
-       case 2: sufftab = vsuf_2; nsuff = ARRAY_SIZE (vsuf_2); break;
-       case 3: sufftab = vsuf_3; nsuff = ARRAY_SIZE (vsuf_3); break;
-       default: goto invalid_suffix;
-       }
-
-      for (i = 0; i < nsuff; i++)
-       if (memcmp (p, sufftab[i].s, end - p) == 0)
-         break;
-      if (i == nsuff)
-       goto invalid_suffix;
-      result.unsignedp = sufftab[i].u;
-
-      if (CPP_WTRADITIONAL (pfile)
-         && sufftab[i].u
-         && ! cpp_sys_macro_p (pfile))
-       cpp_error (pfile, DL_WARNING, "traditional C rejects the `U' suffix");
-      if (sufftab[i].l == 2 && CPP_OPTION (pfile, pedantic)
-         && ! CPP_OPTION (pfile, c99))
-       cpp_error (pfile, DL_PEDWARN,
-                  "too many 'l' suffixes in integer constant");
-    }
-
-  if (big_digit)
-    cpp_error (pfile, DL_PEDWARN,
-              "integer constant contains digits beyond the radix");
-
-  if (overflow)
-    cpp_error (pfile, DL_PEDWARN, "integer constant too large for its type");
-  /* If too big to be signed, consider it unsigned.  */
-  else if (!result.unsignedp && !num_positive (result, precision))
-    {
-      if (base == 10)
-       cpp_error (pfile, DL_WARNING,
-                  "integer constant is so large that it is unsigned");
-      result.unsignedp = 1;
-    }
-
-  return result;
-
- invalid_suffix:
-  cpp_error (pfile, DL_ERROR, "invalid suffix '%.*s' on integer constant",
-            (int) (end - p), p);
- syntax_error:
-  return result;
-}
-
 /* Handle meeting "defined" in a preprocessor expression.  */
 static cpp_num
 parse_defined (pfile)
@@ -379,7 +511,7 @@ parse_defined (pfile)
 
 /* Convert a token into a CPP_NUMBER (an interpreted preprocessing
    number or character constant, or the result of the "defined" or "#"
-   operators), or CPP_ERROR on error.  */
+   operators).  */
 static cpp_num
 eval_token (pfile, token)
      cpp_reader *pfile;
@@ -392,7 +524,26 @@ eval_token (pfile, token)
   switch (token->type)
     {
     case CPP_NUMBER:
-      return interpret_number (pfile, token);
+      temp = cpp_classify_number (pfile, token);
+      switch (temp & CPP_N_CATEGORY)
+       {
+       case CPP_N_FLOATING:
+         cpp_error (pfile, DL_ERROR,
+                    "floating constant in preprocessor expression");
+         break;
+       case CPP_N_INTEGER:
+         if (!(temp & CPP_N_IMAGINARY))
+           return cpp_interpret_integer (pfile, token, temp);
+         cpp_error (pfile, DL_ERROR,
+                    "imaginary number in preprocessor expression");
+         break;
+
+       case CPP_N_INVALID:
+         /* Error already issued.  */
+         break;
+       }
+      result.high = result.low = 0;
+      break;
 
     case CPP_WCHAR:
     case CPP_CHAR:
@@ -604,7 +755,7 @@ _cpp_parse_expr (pfile)
 
        default:
          if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
-           SYNTAX_ERROR2 ("token \"%s\" is not valid in #if expressions",
+           SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions",
                           cpp_token_as_text (pfile, token));
          break;
        }
index af85cc1..a059e2b 100644 (file)
@@ -29,7 +29,6 @@ struct directive;             /* Deliberately incomplete.  */
 struct pending_option;
 struct op;
 
-typedef unsigned HOST_WIDE_INT cpp_num_part;
 typedef unsigned char uchar;
 #define U (const uchar *)  /* Intended use: U"string" */
 
index 86566e5..41842cb 100644 (file)
@@ -1774,6 +1774,9 @@ cpp_post_options (pfile)
   if (CPP_OPTION (pfile, cplusplus))
     CPP_OPTION (pfile, warn_traditional) = 0;
 
+  CPP_OPTION (pfile, warn_long_long) = (CPP_OPTION (pfile, pedantic)
+                                       && !CPP_OPTION (pfile, c99));
+
   /* Permanently disable macro expansion if we are rescanning
      preprocessed text.  Read preprocesed source in ISO mode.  */
   if (CPP_OPTION (pfile, preprocessed))
index 8376e1c..79fff2b 100644 (file)
@@ -327,6 +327,9 @@ struct cpp_options
      traditional C.  */
   unsigned char warn_traditional;
 
+  /* Nonzero means warn about long long numeric constants.  */
+  unsigned char warn_long_long;
+
   /* Nonzero means warn about text after an #endif (or #else).  */
   unsigned char warn_endif_labels;
 
@@ -577,6 +580,51 @@ extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
                                            int, int));
 extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
 
+/* A preprocessing number.  Code assumes that any unused high bits of
+   the double integer are set to zero.  */
+typedef unsigned HOST_WIDE_INT cpp_num_part;
+typedef struct cpp_num cpp_num;
+struct cpp_num
+{
+  cpp_num_part high;
+  cpp_num_part low;
+  bool unsignedp;  /* True if value should be treated as unsigned.  */
+  bool overflow;   /* True if the most recent calculation overflowed.  */
+};
+
+/* cpplib provides two interfaces for interpretation of preprocessing
+   numbers.
+
+   cpp_classify_number categorizes numeric constants according to
+   their field (integer, floating point, or invalid), radix (decimal,
+   octal, hexadecimal), and type suffixes.  */
+
+#define CPP_N_CATEGORY  0x000F
+#define CPP_N_INVALID  0x0000
+#define CPP_N_INTEGER  0x0001
+#define CPP_N_FLOATING 0x0002
+
+#define CPP_N_WIDTH    0x00F0
+#define CPP_N_SMALL    0x0010  /* int, float.  */
+#define CPP_N_MEDIUM   0x0020  /* long, double.  */
+#define CPP_N_LARGE    0x0040  /* long long, long double.  */
+
+#define CPP_N_RADIX    0x0F00
+#define CPP_N_DECIMAL  0x0100
+#define CPP_N_HEX      0x0200
+#define CPP_N_OCTAL    0x0400
+
+#define CPP_N_UNSIGNED 0x1000  /* Properties.  */
+#define CPP_N_IMAGINARY        0x2000
+
+/* Classify a CPP_NUMBER token.  The return value is a combination of
+   the flags from the above sets.  */
+extern unsigned cpp_classify_number PARAMS ((cpp_reader *, const cpp_token *));
+
+/* Evaluate a token classified as category CPP_N_INTEGER.  */
+extern cpp_num cpp_interpret_integer PARAMS ((cpp_reader *, const cpp_token *,
+                                             unsigned int type));
+
 /* Diagnostic levels.  To get a dianostic without associating a
    position in the translation unit with it, use cpp_error_with_line
    with a line number of zero.  */
index a535db2..b3e2fde 100644 (file)
@@ -1,3 +1,9 @@
+2002-05-29  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * gcc.dg/cpp/c++98-pedantic.c, gcc.dg/cpp/c89-pedantic.c, 
+       gcc.dg/cpp/c94-pedantic.c, gcc.dg/cpp/gnuc89-pedantic.c,
+       gcc.dg/cpp/if-1.c: Update for modified diagnostics.
+
 2002-05-29  Hans-Peter Nilsson  <hp@axis.com>
 
        * gcc.c-torture/execute/20020529-1.c: New test.
index 3192a9f..61e13c5 100644 (file)
@@ -6,5 +6,5 @@
 /* This file is for testing the preprocessor in -std=c++98 -pedantic mode.
    Neil Booth, 2 Dec 2000.  */
 
-#if 1LL                                /* { dg-warning "too many" } */
+#if 1LL                                /* { dg-warning "long long" } */
 #endif
index 75051fd..3b7f6dd 100644 (file)
@@ -6,5 +6,5 @@
 /* This file is for testing the preprocessor in -std=c89 -pedantic mode.
    Neil Booth, 2 Dec 2000.  */
 
-#if 1LL                                /* { dg-warning "too many" } */
+#if 1LL                                /* { dg-warning "long long" } */
 #endif
index 589d23c..1c12164 100644 (file)
@@ -6,5 +6,5 @@
 /* This file is for testing the preprocessor in -std=iso9899:199409
    -pedantic mode.  Neil Booth, 2 Dec 2000.  */
 
-#if 1LL                                /* { dg-warning "too many" } */
+#if 1LL                                /* { dg-warning "long long" } */
 #endif
index f9cd968..2749ad7 100644 (file)
@@ -6,5 +6,5 @@
 /* This file is for testing the preprocessor in -std=gnu89 -pedantic mode.
    Neil Booth, 2 Dec 2000.  */
 
-#if 1LL                                /* { dg-warning "too many" } */
+#if 1LL                                /* { dg-warning "long long" } */
 #endif
index c08fd23..c30f215 100644 (file)
@@ -22,7 +22,7 @@
 #error 0xabc   /* { dg-bogus "#error" "normal conversion" } */
 #endif
 
-#if 1.2 /* { dg-error "loating point numbers" "floating point in #if" } */
+#if 1.2 /* { dg-error "loating constant" "floating point in #if" } */
 #endif
 
 #if 4uu /* { dg-error "invalid suffix" "too many suffixes" } */
@@ -34,7 +34,7 @@
 #if 1234lul    /* { dg-error "invalid suffix" "u between ls" } */
 #endif
 
-#if 099 /* { dg-error "digits beyond the radix" "decimal in octal constant" } */
+#if 099 /* { dg-error "invalid digit" "decimal in octal constant" } */
 #endif
 
 #if 0xfffffffffffffffff /* { dg-error "integer constant" "range error" } */