OSDN Git Service

PR driver/27622
[pf3gnuchains/gcc-fork.git] / libcpp / expr.c
index f49bd08..574b85f 100644 (file)
@@ -15,8 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -65,8 +65,8 @@ static unsigned int interpret_int_suffix (const uchar *, size_t);
 static void check_promotion (cpp_reader *, const struct op *);
 
 /* 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)
+#define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1))
+#define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2))
 
 /* With -O2, gcc appears to produce nice code, moving the error
    message load and subsequent jump completely out of the main path.  */
@@ -82,7 +82,7 @@ static void check_promotion (cpp_reader *, const struct op *);
 static unsigned int
 interpret_float_suffix (const uchar *s, size_t len)
 {
-  size_t f = 0, l = 0, i = 0;
+  size_t f = 0, l = 0, i = 0, d = 0;
 
   while (len--)
     switch (s[len])
@@ -91,6 +91,12 @@ interpret_float_suffix (const uchar *s, size_t len)
       case 'l': case 'L': l++; break;
       case 'i': case 'I':
       case 'j': case 'J': i++; break;
+      case 'd': case 'D': 
+       /* Disallow fd, ld suffixes.  */
+       if (d && (f || l))
+         return 0;
+       d++;
+       break;
       default:
        return 0;
       }
@@ -98,9 +104,14 @@ interpret_float_suffix (const uchar *s, size_t len)
   if (f + l > 1 || i > 1)
     return 0;
 
+  /* Allow dd, df, dl suffixes for decimal float constants.  */
+  if (d && ((d + f + l != 2) || i))
+    return 0;
+
   return ((i ? CPP_N_IMAGINARY : 0)
          | (f ? CPP_N_SMALL :
-            l ? CPP_N_LARGE : CPP_N_MEDIUM));
+            l ? CPP_N_LARGE : CPP_N_MEDIUM)
+         | (d ? CPP_N_DFLOAT : 0));
 }
 
 /* Subroutine of cpp_classify_number.  S points to an integer suffix
@@ -250,6 +261,15 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
                   "traditional C rejects the \"%.*s\" suffix",
                   (int) (limit - str), str);
 
+      /* Radix must be 10 for decimal floats.  */
+      if ((result & CPP_N_DFLOAT) && radix != 10)
+        {
+          cpp_error (pfile, CPP_DL_ERROR,
+                     "invalid suffix \"%.*s\" with hexadecimal floating constant",
+                     (int) (limit - str), str);
+          return CPP_N_INVALID;
+        }
+
       result |= CPP_N_FLOATING;
     }
   else
@@ -627,7 +647,7 @@ extra semantics need to be handled with operator-specific code.  */
 
 /* Operator to priority map.  Must be in the same order as the first
    N entries of enum cpp_ttype.  */
-static const struct operator
+static const struct cpp_operator
 {
   uchar prio;
   uchar flags;
@@ -648,9 +668,6 @@ static const struct operator
   /* RSHIFT */         {13, LEFT_ASSOC},
   /* LSHIFT */         {13, LEFT_ASSOC},
 
-  /* MIN */            {10, LEFT_ASSOC | CHECK_PROMOTION},
-  /* MAX */            {10, LEFT_ASSOC | CHECK_PROMOTION},
-
   /* COMPL */          {16, NO_L_OPERAND},
   /* AND_AND */                {6, LEFT_ASSOC},
   /* OR_OR */          {5, LEFT_ASSOC},
@@ -747,18 +764,22 @@ _cpp_parse_expr (cpp_reader *pfile)
        }
       else if (want_value)
        {
-         /* Ordering here is subtle and intended to favor the
-            missing parenthesis diagnostics over alternatives.  */
-         if (op.op == CPP_CLOSE_PAREN)
-           {
-             if (top->op == CPP_OPEN_PAREN)
-               SYNTAX_ERROR ("void expression between '(' and ')'");
-           }
-         else if (top->op == CPP_EOF)
-           SYNTAX_ERROR ("#if with no expression");
-         if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
-           SYNTAX_ERROR2 ("operator '%s' has no right operand",
-                          cpp_token_as_text (pfile, top->token));
+         /* We want a number (or expression) and haven't got one.
+            Try to emit a specific diagnostic.  */
+         if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
+           SYNTAX_ERROR ("missing expression between '(' and ')'");
+
+         if (op.op == CPP_EOF && top->op == CPP_EOF)
+           SYNTAX_ERROR ("#if with no expression");
+
+         if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
+           SYNTAX_ERROR2 ("operator '%s' has no right operand",
+                          cpp_token_as_text (pfile, top->token));
+         else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
+           /* Complain about missing paren during reduction.  */;
+         else
+           SYNTAX_ERROR2 ("operator '%s' has no left operand",
+                          cpp_token_as_text (pfile, op.token));
        }
 
       top = reduce (pfile, top, op.op);
@@ -858,8 +879,6 @@ reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
        case CPP_MINUS:
        case CPP_RSHIFT:
        case CPP_LSHIFT:
-       case CPP_MIN:
-       case CPP_MAX:
        case CPP_COMMA:
          top[-1].value = num_binary_op (pfile, top[-1].value,
                                         top->value, top->op);
@@ -971,7 +990,7 @@ _cpp_expand_op_stack (cpp_reader *pfile)
   size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
   size_t new_size = old_size * 2 + 20;
 
-  pfile->op_stack = xrealloc (pfile->op_stack, new_size * sizeof (struct op));
+  pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size);
   pfile->op_limit = pfile->op_stack + new_size;
 
   return pfile->op_stack + old_size;
@@ -1285,7 +1304,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
 {
   cpp_num result;
   size_t precision = CPP_OPTION (pfile, precision);
-  bool gte;
   size_t n;
 
   switch (op)
@@ -1312,21 +1330,6 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
        lhs = num_rshift (lhs, precision, n);
       break;
 
-      /* Min / Max.  */
-    case CPP_MIN:
-    case CPP_MAX:
-      {
-       bool unsignedp = lhs.unsignedp || rhs.unsignedp;
-
-       gte = num_greater_eq (lhs, rhs, precision);
-       if (op == CPP_MIN)
-         gte = !gte;
-       if (!gte)
-         lhs = rhs;
-       lhs.unsignedp = unsignedp;
-      }
-      break;
-
       /* Arithmetic.  */
     case CPP_MINUS:
       rhs = num_negate (rhs, precision);