OSDN Git Service

* parse.y (trap_overflow_corner_case): New rule.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2001 15:38:10 +0000 (15:38 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2001 15:38:10 +0000 (15:38 +0000)
(unary_expression): Use it.
* lex.c (java_init_lex): Don't set minus_seen.
(yylex): Don't use minus_seen.  Communicate overflow to parser for
it to handle.
(error_if_numeric_overflow): New function.
* parse.h (minus_seen): Removed field.
(JAVA_RADIX10_FLAG): New define.

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

gcc/java/ChangeLog
gcc/java/lex.c
gcc/java/parse.h
gcc/java/parse.y

index ce4073f..a016b69 100644 (file)
@@ -1,3 +1,14 @@
+2001-11-08  Tom Tromey  <tromey@cygnus.com>
+
+       * parse.y (trap_overflow_corner_case): New rule.
+       (unary_expression): Use it.
+       * lex.c (java_init_lex): Don't set minus_seen.
+       (yylex): Don't use minus_seen.  Communicate overflow to parser for
+       it to handle.
+       (error_if_numeric_overflow): New function.
+       * parse.h (minus_seen): Removed field.
+       (JAVA_RADIX10_FLAG): New define.
+
 2001-11-07  Tom Tromey  <tromey@redhat.com>
 
        Patch for PR java/1414:
index 6422f95..779bbcb 100644 (file)
@@ -66,6 +66,9 @@ static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
 #endif
 
 java_lexer *java_new_lexer PARAMS ((FILE *, const char *));
+#ifndef JC1_LITE
+static void error_if_numeric_overflow PARAMS ((tree));
+#endif
 
 #ifdef HAVE_ICONV
 /* This is nonzero if we have initialized `need_byteswap'.  */
@@ -132,7 +135,6 @@ java_init_lex (finput, encoding)
   ctxp->lineno = lineno = 0;
   ctxp->p_line = NULL;
   ctxp->c_line = NULL;
-  ctxp->minus_seen = 0;
   ctxp->java_error_flag = 0;
   ctxp->lexer = java_new_lexer (finput, encoding);
 }
@@ -995,6 +997,7 @@ java_lex (java_lval)
       int  i;
 #ifndef JC1_LITE
       int  number_beginning = ctxp->c_line->current;
+      tree value;
 #endif
       
       /* We might have a . separator instead of a FP like .[0-9]* */
@@ -1233,9 +1236,8 @@ java_lex (java_lval)
             expressed using a 10 radix. For other radixes, everything that
             fits withing 64 bits is OK. */
          int hb = (high >> 31);
-         if (overflow || (hb && low && radix == 10) ||  
-             (hb && high & 0x7fffffff && radix == 10) ||
-             (hb && !(high & 0x7fffffff) && !ctxp->minus_seen && radix == 10))
+         if (overflow || (hb && low && radix == 10)
+             || (hb && high & 0x7fffffff && radix == 10))
            JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal");
        }
       else
@@ -1246,19 +1248,21 @@ java_lex (java_lval)
             that fits within 32 bits is OK.  As all literals are
             signed, we sign extend here. */
          int hb = (low >> 31) & 0x1;
-         if (overflow || high || (hb && low & 0x7fffffff && radix == 10) ||
-             (hb && !(low & 0x7fffffff) && !ctxp->minus_seen && radix == 10))
+         if (overflow || high || (hb && low & 0x7fffffff && radix == 10))
            JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
          high = -hb;
        }
-      ctxp->minus_seen = 0;
+#ifndef JC1_LITE
+      value = build_int_2 (low, high);
+      JAVA_RADIX10_FLAG (value) = radix == 10;
+      SET_LVAL_NODE_TYPE (value, long_suffix ? long_type_node : int_type_node);
+#else
       SET_LVAL_NODE_TYPE (build_int_2 (low, high),
-                         (long_suffix ? long_type_node : int_type_node));
+                         long_suffix ? long_type_node : int_type_node);
+#endif
       return INT_LIT_TK;
     }
 
-  ctxp->minus_seen = 0;
-
   /* Character literals */
   if (c == '\'')
     {
@@ -1475,7 +1479,6 @@ java_lex (java_lval)
          BUILD_OPERATOR2 (MINUS_ASSIGN_TK);
        default:
          java_unget_unicode ();
-         ctxp->minus_seen = 1;
          BUILD_OPERATOR (MINUS_TK);
        }
 
@@ -1649,6 +1652,37 @@ java_lex (java_lval)
   return 0;
 }
 
+#ifndef JC1_LITE
+/* This is called by the parser to see if an error should be generated
+   due to numeric overflow.  This function only handles the particular
+   case of the largest negative value, and is only called in the case
+   where this value is not preceeded by `-'.  */
+static void
+error_if_numeric_overflow (value)
+     tree value;
+{
+  if (TREE_CODE (value) == INTEGER_CST && JAVA_RADIX10_FLAG (value))
+    {
+      unsigned HOST_WIDE_INT lo, hi;
+
+      lo = TREE_INT_CST_LOW (value);
+      hi = TREE_INT_CST_HIGH (value);
+      if (TREE_TYPE (value) == long_type_node)
+       {
+         int hb = (hi >> 31);
+         if (hb && !(hi & 0x7fffffff))
+           java_lex_error ("Numeric overflow for `long' literal", 0);
+       }
+      else
+       {
+         int hb = (lo >> 31) & 0x1;
+         if (hb && !(lo & 0x7fffffff))
+           java_lex_error ("Numeric overflow for `int' literal", 0);
+       }
+    }
+}
+#endif /* JC1_LITE */
+
 static void
 java_unicode_2_utf8 (unicode)
     unicode_t unicode;
index 2205671..b9f4b0f 100644 (file)
@@ -752,8 +752,6 @@ struct parser_ctxt {
   /* Indicates that a context already contains saved data and that the
      next save operation will require a new context to be created. */
   unsigned saved_data:1;
-  /* Integral literal overflow */
-  unsigned minus_seen:1;
   /* Report error when true */
   unsigned java_error_flag:1;
   /* @deprecated tag seen */
@@ -914,6 +912,11 @@ struct parser_ctxt {
   if (CPC_INSTANCE_INITIALIZER_LIST(C))                                \
     TREE_PURPOSE (CPC_INSTANCE_INITIALIZER_LIST (C)) = (S);
 
+/* This is used by the lexer to communicate with the parser.  It is
+   set on an integer constant if the radix is 10, so that the parser
+   can correctly diagnose a numeric overflow.  */
+#define JAVA_RADIX10_FLAG(NODE) TREE_LANG_FLAG_0(NODE)
+
 #ifndef JC1_LITE
 void java_complete_class PARAMS ((void));
 void java_check_circular_reference PARAMS ((void));
index bc79e58..3b9900d 100644 (file)
@@ -577,7 +577,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
                        switch_statement synchronized_statement throw_statement
                        try_statement switch_expression switch_block
                        catches catch_clause catch_clause_parameter finally
-                       anonymous_class_creation
+                       anonymous_class_creation trap_overflow_corner_case
 %type    <node>         return_statement break_statement continue_statement
 
 %type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
@@ -2317,16 +2317,24 @@ post_decrement_expression:
                { $$ = build_incdec ($2.token, $2.location, $1, 1); }
 ;
 
-unary_expression:
+trap_overflow_corner_case:
        pre_increment_expression
 |      pre_decrement_expression
 |      PLUS_TK unary_expression
                {$$ = build_unaryop ($1.token, $1.location, $2); }
-|      MINUS_TK unary_expression
-               {$$ = build_unaryop ($1.token, $1.location, $2); }
 |      unary_expression_not_plus_minus
 |      PLUS_TK error
                {yyerror ("Missing term"); RECOVER}
+;
+
+unary_expression:
+       trap_overflow_corner_case
+               {
+                 error_if_numeric_overflow ($1);
+                 $$ = $1;
+               }
+|      MINUS_TK trap_overflow_corner_case
+               {$$ = build_unaryop ($1.token, $1.location, $2); }
 |      MINUS_TK error
                {yyerror ("Missing term"); RECOVER}
 ;