expr.c (process_jvm_instruction): Do load_type_state after JSR.
authorPer Bothner <bothner@gcc.gnu.org>
Wed, 23 Dec 1998 10:46:45 +0000 (02:46 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Wed, 23 Dec 1998 10:46:45 +0000 (02:46 -0800)
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
gcc/java/parse.c
gcc/java/parse.y
gcc/java/verify.c

index d669cb9bc17d0f10093356b9b15b1ec25f693a41..e07f84d7f978c065170faeae70bf8b2848189dfa 100644 (file)
@@ -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. */
index 9230323cf107f590823af43060440259d3643754..1b6c71ab49d0ecf8393227fd0b30a962573cf9d3 100644 (file)
@@ -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:
index e21e905cb4244c11dc636149c65b450a07679b51..60065d248e603ae2eb85853228fd58b53de1941a 100644 (file)
@@ -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:
index 9554a81d523db13c5712aaba8d060d6acd63fd6a..4e89f4560b2a431b0b70d2c1df3bad691d3eaa49 100644 (file)
@@ -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;