aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/expr.c58
-rw-r--r--gcc/java/ChangeLog5
-rw-r--r--gcc/java/lang.c23
4 files changed, 72 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5bd29d3..55b245a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2002-07-21 Richard Henderson <rth@redhat.com>
+ * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use
+ GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded.
+
+2002-07-21 Richard Henderson <rth@redhat.com>
+
* unroll.c (find_splittable_givs): Do not split DEST_ADDR givs
that are not unrolled completely.
diff --git a/gcc/expr.c b/gcc/expr.c
index 7b5810c..e70bf90 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8965,29 +8965,49 @@ expand_expr (exp, target, tmode, modifier)
{
tree try_block = TREE_OPERAND (exp, 0);
tree finally_block = TREE_OPERAND (exp, 1);
- rtx finally_label = gen_label_rtx ();
- rtx done_label = gen_label_rtx ();
- rtx return_link = gen_reg_rtx (Pmode);
- tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
- (tree) finally_label, (tree) return_link);
- TREE_SIDE_EFFECTS (cleanup) = 1;
- /* Start a new binding layer that will keep track of all cleanup
- actions to be performed. */
- expand_start_bindings (2);
+ if (unsafe_for_reeval (finally_block) > 1)
+ {
+ /* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR
+ is not sufficient, so we cannot expand the block twice.
+ So we play games with GOTO_SUBROUTINE_EXPR to let us
+ expand the thing only once. */
+
+ rtx finally_label = gen_label_rtx ();
+ rtx done_label = gen_label_rtx ();
+ rtx return_link = gen_reg_rtx (Pmode);
+ tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
+ (tree) finally_label, (tree) return_link);
+ TREE_SIDE_EFFECTS (cleanup) = 1;
+
+ /* Start a new binding layer that will keep track of all cleanup
+ actions to be performed. */
+ expand_start_bindings (2);
+ target_temp_slot_level = temp_slot_level;
+
+ expand_decl_cleanup (NULL_TREE, cleanup);
+ op0 = expand_expr (try_block, target, tmode, modifier);
+
+ preserve_temp_slots (op0);
+ expand_end_bindings (NULL_TREE, 0, 0);
+ emit_jump (done_label);
+ emit_label (finally_label);
+ expand_expr (finally_block, const0_rtx, VOIDmode, 0);
+ emit_indirect_jump (return_link);
+ emit_label (done_label);
+ }
+ else
+ {
+ expand_start_bindings (2);
+ target_temp_slot_level = temp_slot_level;
- target_temp_slot_level = temp_slot_level;
+ expand_decl_cleanup (NULL_TREE, finally_block);
+ op0 = expand_expr (try_block, target, tmode, modifier);
- expand_decl_cleanup (NULL_TREE, cleanup);
- op0 = expand_expr (try_block, target, tmode, modifier);
+ preserve_temp_slots (op0);
+ expand_end_bindings (NULL_TREE, 0, 0);
+ }
- preserve_temp_slots (op0);
- expand_end_bindings (NULL_TREE, 0, 0);
- emit_jump (done_label);
- emit_label (finally_label);
- expand_expr (finally_block, const0_rtx, VOIDmode, 0);
- emit_indirect_jump (return_link);
- emit_label (done_label);
return op0;
}
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 601e766..2ccdd05 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,8 @@
+2002-07-21 Richard Henderson <rth@redhat.com>
+
+ * lang.c (java_unsafe_for_reeval): New.
+ (LANG_HOOKS_UNSAFE_FOR_REEVAL): New.
+
2002-07-21 Neil Booth <neil@daikokuya.co.uk>
* jcf-path.c (GET_ENV_PATH_LIST): Remove.
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index 60f1a1c..6d7affa 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -61,6 +61,7 @@ static void java_print_error_function PARAMS ((diagnostic_context *,
static int process_option_with_no PARAMS ((const char *,
const struct string_option *,
int));
+static int java_unsafe_for_reeval PARAMS ((tree));
#ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o"
@@ -238,6 +239,8 @@ struct language_function GTY(())
#define LANG_HOOKS_POST_OPTIONS java_post_options
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE java_parse_file
+#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
+#define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval
#undef LANG_HOOKS_MARK_ADDRESSABLE
#define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
#undef LANG_HOOKS_EXPAND_EXPR
@@ -794,4 +797,24 @@ java_post_options ()
return false;
}
+/* Called from unsafe_for_reeval. */
+static int
+java_unsafe_for_reeval (t)
+ tree t;
+{
+ switch (TREE_CODE (t))
+ {
+ case BLOCK:
+ /* Our expander tries to expand the variables twice. Boom. */
+ if (BLOCK_EXPR_DECLS (t) != NULL)
+ return 2;
+ return unsafe_for_reeval (BLOCK_EXPR_BODY (t));
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
#include "gt-java-lang.h"