From 5a005d9ead24d081423f620a84da54d4a260b001 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Wed, 23 Dec 1998 02:46:45 -0800 Subject: [PATCH] expr.c (process_jvm_instruction): Do load_type_state after JSR. d * expr.c (process_jvm_instruction): Do load_type_state after JSR. * verify.c (verify_jvm_instructions): Fix off-by-one error. * jcf-write.c (CHECK_PUT): Add (void) cast to avoid -Wall warnings. (localvar_alloc): Change return type to void, (emit_unop): Remove unused variable size. * jcf-write.c (struct jcf_block): Add new union. (PENDING_CLEANUP_PC, PENDING_EXIT_PC, UNDEFINED_PC): New macros. (call_cleanups): New functions. (struct jcf_partial): New fields num_finalizers and return_value_decl. (generate_bytecode_insns): Support CLEANUP_POINT_EXPR and WITH_CLEANUP_EXPR. Handle cleanups in RETURN_EXPR and EXIT_BLOCK_EXPR. * lang.c (lang_init): Call using_eh_for_cleanups. * parse.y (java_complete_lhs): For SYNCHRONIZED_EXPR, defer completing operands to patch_synchronized_statement. Support CLEANUP_POINT_EXPR, WITH_CLEANUP_EXPR. (patch_synchronized_statement): Re-write suing CLEANUP_POINT_EXPR and WITH_CLEANUP_EXPR instead of TRY_EXPR. From-SVN: r24406 --- gcc/java/expr.c | 1 + gcc/java/parse.c | 77 ++++++++++++++++++++++++++--------------------- gcc/java/parse.y | 75 ++++++++++++++++++++++++--------------------- gcc/java/verify.c | 8 ++--- 4 files changed, 88 insertions(+), 73 deletions(-) diff --git a/gcc/java/expr.c b/gcc/java/expr.c index d669cb9bc17..e07f84d7f97 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -2191,6 +2191,7 @@ process_jvm_instruction (PC, byte_ops, length) tree where = lookup_label (oldpc+OPERAND_VALUE); \ tree ret = lookup_label (PC); \ build_java_jsr (where, ret); \ + load_type_state (ret); \ } /* Push a constant onto the stack. */ diff --git a/gcc/java/parse.c b/gcc/java/parse.c index 9230323cf10..1b6c71ab49d 100644 --- a/gcc/java/parse.c +++ b/gcc/java/parse.c @@ -2272,7 +2272,7 @@ static const short yycheck[] = { 3, You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. @@ -10129,13 +10129,24 @@ java_complete_lhs (node) case SYNCHRONIZED_EXPR: wfl_op1 = TREE_OPERAND (node, 0); - COMPLETE_CHECK_OP_0 (node); - COMPLETE_CHECK_OP_1 (node); return patch_synchronized_statement (node, wfl_op1); case TRY_EXPR: return patch_try_statement (node); + case CLEANUP_POINT_EXPR: + COMPLETE_CHECK_OP_0 (node); + TREE_TYPE (node) = void_type_node; + CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0)); + return node; + + case WITH_CLEANUP_EXPR: + COMPLETE_CHECK_OP_0 (node); + COMPLETE_CHECK_OP_2 (node); + CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0)); + TREE_TYPE (node) = void_type_node; + return node; + case LABELED_BLOCK_EXPR: PUSH_LABELED_BLOCK (node); if (LABELED_BLOCK_BODY (node)) @@ -13378,12 +13389,19 @@ static tree patch_synchronized_statement (node, wfl_op1) tree node, wfl_op1; { - tree expr = TREE_OPERAND (node, 0); + tree expr = java_complete_tree (TREE_OPERAND (node, 0)); tree block = TREE_OPERAND (node, 1); - tree try_block, catch_all, stmt, compound, decl; + + tree enter, exit, finally, expr_decl; + + if (expr == error_mark_node) + { + block = java_complete_tree (block); + return expr; + } /* The TYPE of expr must be a reference type */ - if (!JREFERENCE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0)))) + if (!JREFERENCE_TYPE_P (TREE_TYPE (expr))) { SET_WFL_OPERATOR (wfl_operator, node, wfl_op1); parse_error_context (wfl_operator, "Incompatible type for `synchronized'" @@ -13409,34 +13427,23 @@ patch_synchronized_statement (node, wfl_op1) Throw (e); } */ - /* TRY block */ - BUILD_MONITOR_ENTER (stmt, expr); - compound = add_stmt_to_compound (NULL_TREE, int_type_node, stmt); - compound = add_stmt_to_compound (compound, void_type_node, block); - if (CAN_COMPLETE_NORMALLY (block)) - { - BUILD_MONITOR_EXIT (stmt, expr); - compound = add_stmt_to_compound (compound, int_type_node, stmt); - } - try_block = build_expr_block (compound, NULL_TREE); - CAN_COMPLETE_NORMALLY (try_block) = CAN_COMPLETE_NORMALLY (block); - - /* CATCH_ALL block */ - decl = build_decl (VAR_DECL, generate_name (), ptr_type_node); - BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl); - compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt); - BUILD_MONITOR_EXIT (stmt, expr); - compound = add_stmt_to_compound (compound, int_type_node, stmt); - BUILD_THROW (stmt, decl); - compound = add_stmt_to_compound (compound, void_type_node, stmt); - catch_all = build_expr_block (compound, decl); - catch_all = build_expr_block (catch_all, NULL_TREE); - catch_all = build1 (CATCH_EXPR, void_type_node, catch_all); - - /* TRY-CATCH statement */ - compound = build (TRY_EXPR, void_type_node, try_block, catch_all, NULL_TREE); - CAN_COMPLETE_NORMALLY (compound) = CAN_COMPLETE_NORMALLY (try_block); - return compound; + expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr)); + BUILD_MONITOR_ENTER (enter, expr_decl); + BUILD_MONITOR_EXIT (exit, expr_decl); + CAN_COMPLETE_NORMALLY (enter) = 1; + CAN_COMPLETE_NORMALLY (exit) = 1; + node = build1 (CLEANUP_POINT_EXPR, NULL_TREE, + build (COMPOUND_EXPR, NULL_TREE, + build (WITH_CLEANUP_EXPR, NULL_TREE, + build (COMPOUND_EXPR, NULL_TREE, + build (MODIFY_EXPR, NULL_TREE, + expr_decl, expr), + enter), + NULL_TREE, exit), + block)); + node = build_expr_block (node, expr_decl); + + return java_complete_tree (node); } /* 14.16 The throw Statement */ @@ -13764,7 +13771,7 @@ fold_constant_for_init (node, context) if (val == NULL_TREE || ! TREE_CONSTANT (val)) return NULL_TREE; TREE_OPERAND (node, 0) = val; - node = patch_unaryop (node, op0); + return patch_unaryop (node, op0); break; case COND_EXPR: diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e21e905cb42..60065d248e6 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -7491,13 +7491,24 @@ java_complete_lhs (node) case SYNCHRONIZED_EXPR: wfl_op1 = TREE_OPERAND (node, 0); - COMPLETE_CHECK_OP_0 (node); - COMPLETE_CHECK_OP_1 (node); return patch_synchronized_statement (node, wfl_op1); case TRY_EXPR: return patch_try_statement (node); + case CLEANUP_POINT_EXPR: + COMPLETE_CHECK_OP_0 (node); + TREE_TYPE (node) = void_type_node; + CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0)); + return node; + + case WITH_CLEANUP_EXPR: + COMPLETE_CHECK_OP_0 (node); + COMPLETE_CHECK_OP_2 (node); + CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0)); + TREE_TYPE (node) = void_type_node; + return node; + case LABELED_BLOCK_EXPR: PUSH_LABELED_BLOCK (node); if (LABELED_BLOCK_BODY (node)) @@ -10740,12 +10751,19 @@ static tree patch_synchronized_statement (node, wfl_op1) tree node, wfl_op1; { - tree expr = TREE_OPERAND (node, 0); + tree expr = java_complete_tree (TREE_OPERAND (node, 0)); tree block = TREE_OPERAND (node, 1); - tree try_block, catch_all, stmt, compound, decl; + + tree enter, exit, finally, expr_decl; + + if (expr == error_mark_node) + { + block = java_complete_tree (block); + return expr; + } /* The TYPE of expr must be a reference type */ - if (!JREFERENCE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0)))) + if (!JREFERENCE_TYPE_P (TREE_TYPE (expr))) { SET_WFL_OPERATOR (wfl_operator, node, wfl_op1); parse_error_context (wfl_operator, "Incompatible type for `synchronized'" @@ -10771,34 +10789,23 @@ patch_synchronized_statement (node, wfl_op1) Throw (e); } */ - /* TRY block */ - BUILD_MONITOR_ENTER (stmt, expr); - compound = add_stmt_to_compound (NULL_TREE, int_type_node, stmt); - compound = add_stmt_to_compound (compound, void_type_node, block); - if (CAN_COMPLETE_NORMALLY (block)) - { - BUILD_MONITOR_EXIT (stmt, expr); - compound = add_stmt_to_compound (compound, int_type_node, stmt); - } - try_block = build_expr_block (compound, NULL_TREE); - CAN_COMPLETE_NORMALLY (try_block) = CAN_COMPLETE_NORMALLY (block); - - /* CATCH_ALL block */ - decl = build_decl (VAR_DECL, generate_name (), ptr_type_node); - BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl); - compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt); - BUILD_MONITOR_EXIT (stmt, expr); - compound = add_stmt_to_compound (compound, int_type_node, stmt); - BUILD_THROW (stmt, decl); - compound = add_stmt_to_compound (compound, void_type_node, stmt); - catch_all = build_expr_block (compound, decl); - catch_all = build_expr_block (catch_all, NULL_TREE); - catch_all = build1 (CATCH_EXPR, void_type_node, catch_all); - - /* TRY-CATCH statement */ - compound = build (TRY_EXPR, void_type_node, try_block, catch_all, NULL_TREE); - CAN_COMPLETE_NORMALLY (compound) = CAN_COMPLETE_NORMALLY (try_block); - return compound; + expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr)); + BUILD_MONITOR_ENTER (enter, expr_decl); + BUILD_MONITOR_EXIT (exit, expr_decl); + CAN_COMPLETE_NORMALLY (enter) = 1; + CAN_COMPLETE_NORMALLY (exit) = 1; + node = build1 (CLEANUP_POINT_EXPR, NULL_TREE, + build (COMPOUND_EXPR, NULL_TREE, + build (WITH_CLEANUP_EXPR, NULL_TREE, + build (COMPOUND_EXPR, NULL_TREE, + build (MODIFY_EXPR, NULL_TREE, + expr_decl, expr), + enter), + NULL_TREE, exit), + block)); + node = build_expr_block (node, expr_decl); + + return java_complete_tree (node); } /* 14.16 The throw Statement */ @@ -11126,7 +11133,7 @@ fold_constant_for_init (node, context) if (val == NULL_TREE || ! TREE_CONSTANT (val)) return NULL_TREE; TREE_OPERAND (node, 0) = val; - node = patch_unaryop (node, op0); + return patch_unaryop (node, op0); break; case COND_EXPR: diff --git a/gcc/java/verify.c b/gcc/java/verify.c index 9554a81d523..4e89f4560b2 100644 --- a/gcc/java/verify.c +++ b/gcc/java/verify.c @@ -1035,10 +1035,10 @@ verify_jvm_instructions (jcf, byte_ops, length) int nlocals = DECL_MAX_LOCALS (current_function_decl); index = nlocals + DECL_MAX_STACK (current_function_decl); return_type_map = make_tree_vec (index); - while (--index >= nlocals) - TREE_VEC_ELT (return_type_map, index) = TYPE_UNKNOWN; - while (--index >= 0) - TREE_VEC_ELT (return_type_map, index) = TYPE_UNUSED; + while (index > nlocals) + TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN; + while (index > 0) + TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED; LABEL_RETURN_LABEL (target) = build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target)); LABEL_PC (LABEL_RETURN_LABEL (target)) = -1; -- 2.30.2