Force left-to-right evaluation of binary operations etc.
d Force left-to-right evaluation of binary operations etc. * expr.c (force_evaluation_order), java-tree.h: New function. * parse.y (java_complete_lhs): Pass binary operations, procedure calls, and ARRAY_REFs to force_evaluation_order. (various): Set TREE_SIDE_EFFECTS more carefully. Tolerate random (non-UTF8) encoding in comments without complaining. * lex.c (java_read_char): Return 0xFFFE if bad UTF8 encoding. (java_is_eol): Handle '\r' followed by '\n' instead of vice versa. * parse.y (resolve_qualified_expression_name): Handle error_mark. (java_complete_node case EXPR_WITH_FILE_LOCATION): Likewise. * parse.y (java_complete_lhs): Ignore an empty statement in a COMPOUND_EXPR. Don't complain about empty statement after return. From-SVN: r25328
This commit is contained in:
parent
68ae3b17eb
commit
dc0b3eff72
@ -197,6 +197,8 @@ java_allocate_new_line ()
|
||||
ctxp->c_line->white_space_only = 1;
|
||||
}
|
||||
|
||||
#define BAD_UTF8_VALUE 0xFFFE
|
||||
|
||||
static unicode_t
|
||||
java_read_char ()
|
||||
{
|
||||
@ -235,9 +237,8 @@ java_read_char ()
|
||||
(( c1 & 0x3f) << 6) + (c2 & 0x3f));
|
||||
}
|
||||
}
|
||||
java_lex_error ("Bad utf8 encoding", 0);
|
||||
return BAD_UTF8_VALUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1312,12 +1313,12 @@ java_is_eol (fp, c)
|
||||
int next;
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
next = getc (fp);
|
||||
if (next != '\r' && next != EOF)
|
||||
if (next != '\n' && next != EOF)
|
||||
ungetc (next, fp);
|
||||
return 1;
|
||||
case '\r':
|
||||
case '\n':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -6450,8 +6450,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(field_decl =
|
||||
lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
|
||||
field_decl = lookup_field_wrapper (type,
|
||||
EXPR_WFL_NODE (qual_wfl));
|
||||
if (field_decl == NULL_TREE)
|
||||
{
|
||||
parse_error_context
|
||||
(qual_wfl, "No variable `%s' defined in class `%s'",
|
||||
@ -6459,6 +6460,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
|
||||
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
|
||||
return 1;
|
||||
}
|
||||
if (field_decl == error_mark_node)
|
||||
return 1;
|
||||
|
||||
/* Layout the type of field_decl, since we may need
|
||||
it. Don't do primitive types or loaded classes. The
|
||||
@ -7576,7 +7579,8 @@ java_complete_lhs (node)
|
||||
/* Now do the actual complete, without deep recursion for
|
||||
long blocks. */
|
||||
ptr = &BLOCK_EXPR_BODY (node);
|
||||
while (TREE_CODE (*ptr) == COMPOUND_EXPR)
|
||||
while (TREE_CODE (*ptr) == COMPOUND_EXPR
|
||||
&& TREE_OPERAND (*ptr, 1) != empty_stmt_node)
|
||||
{
|
||||
tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
|
||||
tree *next = &TREE_OPERAND (*ptr, 1);
|
||||
@ -7596,8 +7600,7 @@ java_complete_lhs (node)
|
||||
break;
|
||||
}
|
||||
if (TREE_CODE (wfl_op2) != CASE_EXPR
|
||||
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR
|
||||
&& wfl_op2 != empty_stmt_node)
|
||||
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR)
|
||||
unreachable_stmt_error (*ptr);
|
||||
}
|
||||
ptr = next;
|
||||
@ -7787,26 +7790,30 @@ java_complete_lhs (node)
|
||||
wfl_op2 = TREE_OPERAND (node, 1);
|
||||
TREE_OPERAND (node, 0) = nn =
|
||||
java_complete_tree (TREE_OPERAND (node, 0));
|
||||
if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK
|
||||
&& wfl_op2 != empty_stmt_node)
|
||||
if (wfl_op2 == empty_stmt_node)
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
|
||||
else
|
||||
{
|
||||
/* An unreachable condition in a do-while statement
|
||||
is *not* (technically) an unreachable statement. */
|
||||
nn = wfl_op2;
|
||||
if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
|
||||
nn = EXPR_WFL_NODE (nn);
|
||||
if (TREE_CODE (nn) != EXIT_EXPR)
|
||||
if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
|
||||
{
|
||||
SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
|
||||
parse_error_context (wfl_operator, "Unreachable statement");
|
||||
/* An unreachable condition in a do-while statement
|
||||
is *not* (technically) an unreachable statement. */
|
||||
nn = wfl_op2;
|
||||
if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
|
||||
nn = EXPR_WFL_NODE (nn);
|
||||
if (TREE_CODE (nn) != EXIT_EXPR)
|
||||
{
|
||||
SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
|
||||
parse_error_context (wfl_operator, "Unreachable statement");
|
||||
}
|
||||
}
|
||||
TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
|
||||
if (TREE_OPERAND (node, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
CAN_COMPLETE_NORMALLY (node)
|
||||
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
|
||||
}
|
||||
TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
|
||||
if (TREE_OPERAND (node, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
|
||||
CAN_COMPLETE_NORMALLY (node)
|
||||
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
|
||||
break;
|
||||
|
||||
case RETURN_EXPR:
|
||||
@ -7818,6 +7825,8 @@ java_complete_lhs (node)
|
||||
|| TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
|
||||
{
|
||||
node = resolve_expression_name (node, NULL);
|
||||
if (node == error_mark_node)
|
||||
return node;
|
||||
CAN_COMPLETE_NORMALLY (node) = 1;
|
||||
}
|
||||
else
|
||||
@ -7828,9 +7837,9 @@ java_complete_lhs (node)
|
||||
body = java_complete_tree (EXPR_WFL_NODE (node));
|
||||
lineno = save_lineno;
|
||||
EXPR_WFL_NODE (node) = body;
|
||||
TREE_SIDE_EFFECTS (node) = 1;
|
||||
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
|
||||
if (EXPR_WFL_NODE (node) == error_mark_node)
|
||||
if (body == error_mark_node)
|
||||
{
|
||||
/* Its important for the evaluation of assignment that
|
||||
this mark on the TREE_TYPE is propagated. */
|
||||
@ -7892,7 +7901,7 @@ java_complete_lhs (node)
|
||||
tree_cons (wfl, decl,
|
||||
DECL_CONSTRUCTOR_CALLS (current_function_decl));
|
||||
CAN_COMPLETE_NORMALLY (node) = 1;
|
||||
return node;
|
||||
return force_evaluation_order (node);
|
||||
}
|
||||
|
||||
case MODIFY_EXPR:
|
||||
@ -8001,7 +8010,7 @@ java_complete_lhs (node)
|
||||
if (TREE_OPERAND (node, 1) == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
return patch_binop (node, wfl_op1, wfl_op2);
|
||||
return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
|
||||
|
||||
case INSTANCEOF_EXPR:
|
||||
wfl_op1 = TREE_OPERAND (node, 0);
|
||||
@ -8044,7 +8053,7 @@ java_complete_lhs (node)
|
||||
return error_mark_node;
|
||||
if (!flag_emit_class_files)
|
||||
TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
|
||||
return patch_array_ref (node);
|
||||
return force_evaluation_order (patch_array_ref (node));
|
||||
|
||||
case RECORD_TYPE:
|
||||
return node;;
|
||||
@ -8971,6 +8980,8 @@ patch_binop (node, wfl_op1, wfl_op2)
|
||||
{
|
||||
tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
|
||||
COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
|
||||
TREE_SIDE_EFFECTS (mod)
|
||||
= TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
|
||||
return mod;
|
||||
}
|
||||
break;
|
||||
@ -9057,6 +9068,8 @@ patch_binop (node, wfl_op1, wfl_op2)
|
||||
to_return = convert (prom_type, node);
|
||||
/* Copy the original value of the COMPOUND_ASSIGN_P flag */
|
||||
COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
|
||||
TREE_SIDE_EFFECTS (to_return)
|
||||
= TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
|
||||
return to_return;
|
||||
}
|
||||
break;
|
||||
@ -9091,6 +9104,7 @@ patch_binop (node, wfl_op1, wfl_op2)
|
||||
else if (flag_emit_class_files)
|
||||
{
|
||||
TREE_OPERAND (node, 1) = op2_type;
|
||||
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
|
||||
return node;
|
||||
}
|
||||
/* Otherwise we have to invoke instance of to figure it out */
|
||||
@ -9104,7 +9118,7 @@ patch_binop (node, wfl_op1, wfl_op2)
|
||||
build_tree_list (NULL_TREE,
|
||||
build_class_ref (op2_type))),
|
||||
NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (call) = 1;
|
||||
TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
|
||||
return call;
|
||||
}
|
||||
}
|
||||
@ -9241,6 +9255,8 @@ patch_binop (node, wfl_op1, wfl_op2)
|
||||
TREE_OPERAND (node, 0) = op1;
|
||||
TREE_OPERAND (node, 1) = op2;
|
||||
TREE_TYPE (node) = prom_type;
|
||||
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
|
||||
|
||||
return fold (node);
|
||||
}
|
||||
|
||||
@ -9360,6 +9376,8 @@ build_string_concatenation (op1, op2)
|
||||
tree op1, op2;
|
||||
{
|
||||
tree result;
|
||||
int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
|
||||
|
||||
|
||||
/* Try to do some static optimization */
|
||||
if ((result = string_constant_concatenation (op1, op2)))
|
||||
@ -9412,7 +9430,8 @@ build_string_concatenation (op1, op2)
|
||||
|
||||
/* Mark the last node holding a crafted StringBuffer */
|
||||
IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
|
||||
|
||||
|
||||
TREE_SIDE_EFFECTS (op1) = side_effects;
|
||||
return op1;
|
||||
}
|
||||
|
||||
@ -9662,7 +9681,11 @@ patch_unaryop (node, wfl_op)
|
||||
error_found = 1;
|
||||
}
|
||||
else
|
||||
return fold (value);
|
||||
{
|
||||
value = fold (value);
|
||||
TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
|
||||
return value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -9674,6 +9697,7 @@ patch_unaryop (node, wfl_op)
|
||||
CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
|
||||
TREE_OPERAND (node, 0) = fold (op);
|
||||
TREE_TYPE (node) = prom_type;
|
||||
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
|
||||
return fold (node);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user