Commit dc0b3eff by Per Bothner

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
parent 68ae3b17
...@@ -197,6 +197,8 @@ java_allocate_new_line () ...@@ -197,6 +197,8 @@ java_allocate_new_line ()
ctxp->c_line->white_space_only = 1; ctxp->c_line->white_space_only = 1;
} }
#define BAD_UTF8_VALUE 0xFFFE
static unicode_t static unicode_t
java_read_char () java_read_char ()
{ {
...@@ -235,9 +237,8 @@ java_read_char () ...@@ -235,9 +237,8 @@ java_read_char ()
(( c1 & 0x3f) << 6) + (c2 & 0x3f)); (( c1 & 0x3f) << 6) + (c2 & 0x3f));
} }
} }
java_lex_error ("Bad utf8 encoding", 0); return BAD_UTF8_VALUE;
} }
return 0;
} }
static void static void
...@@ -1312,12 +1313,12 @@ java_is_eol (fp, c) ...@@ -1312,12 +1313,12 @@ java_is_eol (fp, c)
int next; int next;
switch (c) switch (c)
{ {
case '\n': case '\r':
next = getc (fp); next = getc (fp);
if (next != '\r' && next != EOF) if (next != '\n' && next != EOF)
ungetc (next, fp); ungetc (next, fp);
return 1; return 1;
case '\r': case '\n':
return 1; return 1;
default: default:
return 0; return 0;
......
...@@ -6450,8 +6450,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -6450,8 +6450,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
return 1; return 1;
} }
if (!(field_decl = field_decl = lookup_field_wrapper (type,
lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl)))) EXPR_WFL_NODE (qual_wfl));
if (field_decl == NULL_TREE)
{ {
parse_error_context parse_error_context
(qual_wfl, "No variable `%s' defined in class `%s'", (qual_wfl, "No variable `%s' defined in class `%s'",
...@@ -6459,6 +6460,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -6459,6 +6460,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
return 1; return 1;
} }
if (field_decl == error_mark_node)
return 1;
/* Layout the type of field_decl, since we may need /* Layout the type of field_decl, since we may need
it. Don't do primitive types or loaded classes. The it. Don't do primitive types or loaded classes. The
...@@ -7576,7 +7579,8 @@ java_complete_lhs (node) ...@@ -7576,7 +7579,8 @@ java_complete_lhs (node)
/* Now do the actual complete, without deep recursion for /* Now do the actual complete, without deep recursion for
long blocks. */ long blocks. */
ptr = &BLOCK_EXPR_BODY (node); 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 cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
tree *next = &TREE_OPERAND (*ptr, 1); tree *next = &TREE_OPERAND (*ptr, 1);
...@@ -7596,8 +7600,7 @@ java_complete_lhs (node) ...@@ -7596,8 +7600,7 @@ java_complete_lhs (node)
break; break;
} }
if (TREE_CODE (wfl_op2) != CASE_EXPR if (TREE_CODE (wfl_op2) != CASE_EXPR
&& TREE_CODE (wfl_op2) != DEFAULT_EXPR && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
&& wfl_op2 != empty_stmt_node)
unreachable_stmt_error (*ptr); unreachable_stmt_error (*ptr);
} }
ptr = next; ptr = next;
...@@ -7787,26 +7790,30 @@ java_complete_lhs (node) ...@@ -7787,26 +7790,30 @@ java_complete_lhs (node)
wfl_op2 = TREE_OPERAND (node, 1); wfl_op2 = TREE_OPERAND (node, 1);
TREE_OPERAND (node, 0) = nn = TREE_OPERAND (node, 0) = nn =
java_complete_tree (TREE_OPERAND (node, 0)); java_complete_tree (TREE_OPERAND (node, 0));
if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK if (wfl_op2 == empty_stmt_node)
&& 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. */ if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
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); /* An unreachable condition in a do-while statement
parse_error_context (wfl_operator, "Unreachable 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)); TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
CAN_COMPLETE_NORMALLY (node)
= CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
break; break;
case RETURN_EXPR: case RETURN_EXPR:
...@@ -7818,6 +7825,8 @@ java_complete_lhs (node) ...@@ -7818,6 +7825,8 @@ java_complete_lhs (node)
|| TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE) || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
{ {
node = resolve_expression_name (node, NULL); node = resolve_expression_name (node, NULL);
if (node == error_mark_node)
return node;
CAN_COMPLETE_NORMALLY (node) = 1; CAN_COMPLETE_NORMALLY (node) = 1;
} }
else else
...@@ -7828,9 +7837,9 @@ java_complete_lhs (node) ...@@ -7828,9 +7837,9 @@ java_complete_lhs (node)
body = java_complete_tree (EXPR_WFL_NODE (node)); body = java_complete_tree (EXPR_WFL_NODE (node));
lineno = save_lineno; lineno = save_lineno;
EXPR_WFL_NODE (node) = body; 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); 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 /* Its important for the evaluation of assignment that
this mark on the TREE_TYPE is propagated. */ this mark on the TREE_TYPE is propagated. */
...@@ -7892,7 +7901,7 @@ java_complete_lhs (node) ...@@ -7892,7 +7901,7 @@ java_complete_lhs (node)
tree_cons (wfl, decl, tree_cons (wfl, decl,
DECL_CONSTRUCTOR_CALLS (current_function_decl)); DECL_CONSTRUCTOR_CALLS (current_function_decl));
CAN_COMPLETE_NORMALLY (node) = 1; CAN_COMPLETE_NORMALLY (node) = 1;
return node; return force_evaluation_order (node);
} }
case MODIFY_EXPR: case MODIFY_EXPR:
...@@ -8001,7 +8010,7 @@ java_complete_lhs (node) ...@@ -8001,7 +8010,7 @@ java_complete_lhs (node)
if (TREE_OPERAND (node, 1) == error_mark_node) if (TREE_OPERAND (node, 1) == error_mark_node)
return 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: case INSTANCEOF_EXPR:
wfl_op1 = TREE_OPERAND (node, 0); wfl_op1 = TREE_OPERAND (node, 0);
...@@ -8044,7 +8053,7 @@ java_complete_lhs (node) ...@@ -8044,7 +8053,7 @@ java_complete_lhs (node)
return error_mark_node; return error_mark_node;
if (!flag_emit_class_files) if (!flag_emit_class_files)
TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1)); 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: case RECORD_TYPE:
return node;; return node;;
...@@ -8971,6 +8980,8 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -8971,6 +8980,8 @@ patch_binop (node, wfl_op1, wfl_op2)
{ {
tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2); tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node); COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
TREE_SIDE_EFFECTS (mod)
= TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
return mod; return mod;
} }
break; break;
...@@ -9057,6 +9068,8 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -9057,6 +9068,8 @@ patch_binop (node, wfl_op1, wfl_op2)
to_return = convert (prom_type, node); to_return = convert (prom_type, node);
/* Copy the original value of the COMPOUND_ASSIGN_P flag */ /* Copy the original value of the COMPOUND_ASSIGN_P flag */
COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node); 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; return to_return;
} }
break; break;
...@@ -9091,6 +9104,7 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -9091,6 +9104,7 @@ patch_binop (node, wfl_op1, wfl_op2)
else if (flag_emit_class_files) else if (flag_emit_class_files)
{ {
TREE_OPERAND (node, 1) = op2_type; TREE_OPERAND (node, 1) = op2_type;
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
return node; return node;
} }
/* Otherwise we have to invoke instance of to figure it out */ /* Otherwise we have to invoke instance of to figure it out */
...@@ -9104,7 +9118,7 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -9104,7 +9118,7 @@ patch_binop (node, wfl_op1, wfl_op2)
build_tree_list (NULL_TREE, build_tree_list (NULL_TREE,
build_class_ref (op2_type))), build_class_ref (op2_type))),
NULL_TREE); NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1; TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
return call; return call;
} }
} }
...@@ -9241,6 +9255,8 @@ patch_binop (node, wfl_op1, wfl_op2) ...@@ -9241,6 +9255,8 @@ patch_binop (node, wfl_op1, wfl_op2)
TREE_OPERAND (node, 0) = op1; TREE_OPERAND (node, 0) = op1;
TREE_OPERAND (node, 1) = op2; TREE_OPERAND (node, 1) = op2;
TREE_TYPE (node) = prom_type; TREE_TYPE (node) = prom_type;
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
return fold (node); return fold (node);
} }
...@@ -9360,6 +9376,8 @@ build_string_concatenation (op1, op2) ...@@ -9360,6 +9376,8 @@ build_string_concatenation (op1, op2)
tree op1, op2; tree op1, op2;
{ {
tree result; tree result;
int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
/* Try to do some static optimization */ /* Try to do some static optimization */
if ((result = string_constant_concatenation (op1, op2))) if ((result = string_constant_concatenation (op1, op2)))
...@@ -9412,7 +9430,8 @@ build_string_concatenation (op1, op2) ...@@ -9412,7 +9430,8 @@ build_string_concatenation (op1, op2)
/* Mark the last node holding a crafted StringBuffer */ /* Mark the last node holding a crafted StringBuffer */
IS_CRAFTED_STRING_BUFFER_P (op1) = 1; IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
TREE_SIDE_EFFECTS (op1) = side_effects;
return op1; return op1;
} }
...@@ -9662,7 +9681,11 @@ patch_unaryop (node, wfl_op) ...@@ -9662,7 +9681,11 @@ patch_unaryop (node, wfl_op)
error_found = 1; error_found = 1;
} }
else else
return fold (value); {
value = fold (value);
TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
return value;
}
break; break;
} }
...@@ -9674,6 +9697,7 @@ patch_unaryop (node, wfl_op) ...@@ -9674,6 +9697,7 @@ patch_unaryop (node, wfl_op)
CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */ CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
TREE_OPERAND (node, 0) = fold (op); TREE_OPERAND (node, 0) = fold (op);
TREE_TYPE (node) = prom_type; TREE_TYPE (node) = prom_type;
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
return fold (node); return fold (node);
} }
......
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