From dc0b3eff7222829d8ae75f4791aa16e617a03f23 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Fri, 19 Feb 1999 08:33:22 -0800 Subject: [PATCH] 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 --- gcc/java/lex.c | 11 ++++--- gcc/java/parse.y | 82 +++++++++++++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/gcc/java/lex.c b/gcc/java/lex.c index 89b3fb2d305..98606cc3021 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -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; diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 7e5eeca6d2f..b548ad1b1a1 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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) - { - /* 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 (wfl_op2 == empty_stmt_node) + CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn); + else + { + 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); } -- 2.30.2