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:
parent
5a21a051b7
commit
1fa73144cb
4 changed files with 73 additions and 17 deletions
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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}
|
||||
;
|
||||
|
|
Loading…
Add table
Reference in a new issue