Commit 1fa73144 by Tom Tromey Committed by Tom Tromey

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
parent 5a21a051
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> 2001-11-07 Tom Tromey <tromey@redhat.com>
Patch for PR java/1414: Patch for PR java/1414:
......
...@@ -66,6 +66,9 @@ static int utf8_cmp PARAMS ((const unsigned char *, int, const char *)); ...@@ -66,6 +66,9 @@ static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
#endif #endif
java_lexer *java_new_lexer PARAMS ((FILE *, const char *)); java_lexer *java_new_lexer PARAMS ((FILE *, const char *));
#ifndef JC1_LITE
static void error_if_numeric_overflow PARAMS ((tree));
#endif
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
/* This is nonzero if we have initialized `need_byteswap'. */ /* This is nonzero if we have initialized `need_byteswap'. */
...@@ -132,7 +135,6 @@ java_init_lex (finput, encoding) ...@@ -132,7 +135,6 @@ java_init_lex (finput, encoding)
ctxp->lineno = lineno = 0; ctxp->lineno = lineno = 0;
ctxp->p_line = NULL; ctxp->p_line = NULL;
ctxp->c_line = NULL; ctxp->c_line = NULL;
ctxp->minus_seen = 0;
ctxp->java_error_flag = 0; ctxp->java_error_flag = 0;
ctxp->lexer = java_new_lexer (finput, encoding); ctxp->lexer = java_new_lexer (finput, encoding);
} }
...@@ -995,6 +997,7 @@ java_lex (java_lval) ...@@ -995,6 +997,7 @@ java_lex (java_lval)
int i; int i;
#ifndef JC1_LITE #ifndef JC1_LITE
int number_beginning = ctxp->c_line->current; int number_beginning = ctxp->c_line->current;
tree value;
#endif #endif
/* We might have a . separator instead of a FP like .[0-9]* */ /* We might have a . separator instead of a FP like .[0-9]* */
...@@ -1233,9 +1236,8 @@ java_lex (java_lval) ...@@ -1233,9 +1236,8 @@ java_lex (java_lval)
expressed using a 10 radix. For other radixes, everything that expressed using a 10 radix. For other radixes, everything that
fits withing 64 bits is OK. */ fits withing 64 bits is OK. */
int hb = (high >> 31); int hb = (high >> 31);
if (overflow || (hb && low && radix == 10) || if (overflow || (hb && low && radix == 10)
(hb && high & 0x7fffffff && radix == 10) || || (hb && high & 0x7fffffff && radix == 10))
(hb && !(high & 0x7fffffff) && !ctxp->minus_seen && radix == 10))
JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal"); JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal");
} }
else else
...@@ -1246,19 +1248,21 @@ java_lex (java_lval) ...@@ -1246,19 +1248,21 @@ java_lex (java_lval)
that fits within 32 bits is OK. As all literals are that fits within 32 bits is OK. As all literals are
signed, we sign extend here. */ signed, we sign extend here. */
int hb = (low >> 31) & 0x1; int hb = (low >> 31) & 0x1;
if (overflow || high || (hb && low & 0x7fffffff && radix == 10) || if (overflow || high || (hb && low & 0x7fffffff && radix == 10))
(hb && !(low & 0x7fffffff) && !ctxp->minus_seen && radix == 10))
JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal"); JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal");
high = -hb; 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), 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; return INT_LIT_TK;
} }
ctxp->minus_seen = 0;
/* Character literals */ /* Character literals */
if (c == '\'') if (c == '\'')
{ {
...@@ -1475,7 +1479,6 @@ java_lex (java_lval) ...@@ -1475,7 +1479,6 @@ java_lex (java_lval)
BUILD_OPERATOR2 (MINUS_ASSIGN_TK); BUILD_OPERATOR2 (MINUS_ASSIGN_TK);
default: default:
java_unget_unicode (); java_unget_unicode ();
ctxp->minus_seen = 1;
BUILD_OPERATOR (MINUS_TK); BUILD_OPERATOR (MINUS_TK);
} }
...@@ -1649,6 +1652,37 @@ java_lex (java_lval) ...@@ -1649,6 +1652,37 @@ java_lex (java_lval)
return 0; 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 static void
java_unicode_2_utf8 (unicode) java_unicode_2_utf8 (unicode)
unicode_t unicode; unicode_t unicode;
......
...@@ -752,8 +752,6 @@ struct parser_ctxt { ...@@ -752,8 +752,6 @@ struct parser_ctxt {
/* Indicates that a context already contains saved data and that the /* Indicates that a context already contains saved data and that the
next save operation will require a new context to be created. */ next save operation will require a new context to be created. */
unsigned saved_data:1; unsigned saved_data:1;
/* Integral literal overflow */
unsigned minus_seen:1;
/* Report error when true */ /* Report error when true */
unsigned java_error_flag:1; unsigned java_error_flag:1;
/* @deprecated tag seen */ /* @deprecated tag seen */
...@@ -914,6 +912,11 @@ struct parser_ctxt { ...@@ -914,6 +912,11 @@ struct parser_ctxt {
if (CPC_INSTANCE_INITIALIZER_LIST(C)) \ if (CPC_INSTANCE_INITIALIZER_LIST(C)) \
TREE_PURPOSE (CPC_INSTANCE_INITIALIZER_LIST (C)) = (S); 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 #ifndef JC1_LITE
void java_complete_class PARAMS ((void)); void java_complete_class PARAMS ((void));
void java_check_circular_reference PARAMS ((void)); void java_check_circular_reference PARAMS ((void));
......
...@@ -577,7 +577,7 @@ static tree src_parse_roots[1] = { NULL_TREE }; ...@@ -577,7 +577,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
switch_statement synchronized_statement throw_statement switch_statement synchronized_statement throw_statement
try_statement switch_expression switch_block try_statement switch_expression switch_block
catches catch_clause catch_clause_parameter finally 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 <node> return_statement break_statement continue_statement
%type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK %type <operator> ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
...@@ -2317,16 +2317,24 @@ post_decrement_expression: ...@@ -2317,16 +2317,24 @@ post_decrement_expression:
{ $$ = build_incdec ($2.token, $2.location, $1, 1); } { $$ = build_incdec ($2.token, $2.location, $1, 1); }
; ;
unary_expression: trap_overflow_corner_case:
pre_increment_expression pre_increment_expression
| pre_decrement_expression | pre_decrement_expression
| PLUS_TK unary_expression | PLUS_TK unary_expression
{$$ = build_unaryop ($1.token, $1.location, $2); } {$$ = build_unaryop ($1.token, $1.location, $2); }
| MINUS_TK unary_expression
{$$ = build_unaryop ($1.token, $1.location, $2); }
| unary_expression_not_plus_minus | unary_expression_not_plus_minus
| PLUS_TK error | PLUS_TK error
{yyerror ("Missing term"); RECOVER} {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 | MINUS_TK error
{yyerror ("Missing term"); RECOVER} {yyerror ("Missing term"); RECOVER}
; ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment