diff options
author | Tom Tromey <tromey@cygnus.com> | 2001-11-08 15:38:10 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2001-11-08 15:38:10 +0000 |
commit | 1fa73144cba39152fd2142bebcfd0b1faa6fbeaf (patch) | |
tree | 8d9569c5e98df492ddd441e2d8ef2f828d2237e2 /gcc/java | |
parent | 5a21a051b749b5b61090d9c08a719057c3fa959f (diff) | |
download | gcc-1fa73144cba39152fd2142bebcfd0b1faa6fbeaf.zip gcc-1fa73144cba39152fd2142bebcfd0b1faa6fbeaf.tar.gz gcc-1fa73144cba39152fd2142bebcfd0b1faa6fbeaf.tar.bz2 |
parse.y (trap_overflow_corner_case): New rule.
* 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.
From-SVN: r46846
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/java/lex.c | 56 | ||||
-rw-r--r-- | gcc/java/parse.h | 7 | ||||
-rw-r--r-- | gcc/java/parse.y | 16 |
4 files changed, 73 insertions, 17 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index ce4073f..a016b69 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -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: diff --git a/gcc/java/lex.c b/gcc/java/lex.c index 6422f95..779bbcb 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -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; diff --git a/gcc/java/parse.h b/gcc/java/parse.h index 22056715..b9f4b0f 100644 --- a/gcc/java/parse.h +++ b/gcc/java/parse.h @@ -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)); diff --git a/gcc/java/parse.y b/gcc/java/parse.y index bc79e58..3b9900d 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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} ; |