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
This commit is contained in:
Tom Tromey 2001-11-08 15:38:10 +00:00 committed by Tom Tromey
parent 5a21a051b7
commit 1fa73144cb
4 changed files with 73 additions and 17 deletions

View 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:

View 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;

View 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));

View 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}
;