This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] fix 21_strings/basic_string/operators/char/1.cc
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 18 Sep 2003 23:25:05 -0700
- Subject: [tree-ssa] fix 21_strings/basic_string/operators/char/1.cc
Problem here is that copying blocks means that we have new copies
of labels within that new block. Since we hadn't recorded the
existance and position of these new labels within the finally tree,
we considered branches to these labels to leave *all* finally blocks.
Which results in double destruction.
Surprisingly, most objects seem to be quite tolerant of this.
r~
* tree-eh.c (lower_try_finally_dup_block): New.
(honor_protect_cleanup_actions, lower_try_finally_copy): Use it.
Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-eh.c,v
retrieving revision 1.1.2.4
diff -u -p -u -r1.1.2.4 tree-eh.c
--- tree-eh.c 18 Sep 2003 20:25:38 -0000 1.1.2.4
+++ tree-eh.c 19 Sep 2003 06:14:22 -0000
@@ -641,6 +641,23 @@ frob_into_branch_around (tree *tp, tree
}
}
+/* A subroutine of lower_try_finally. Duplicate the tree rooted at T.
+ Make sure to record all new labels found. */
+
+static tree
+lower_try_finally_dup_block (tree t, struct leh_state *outer_state)
+{
+ tree region = NULL;
+
+ t = lhd_unsave_expr_now (t);
+
+ if (outer_state->tf)
+ region = outer_state->tf->try_finally_expr;
+ collect_finally_tree (t, region);
+
+ return t;
+}
+
/* A subroutine of lower_try_finally. If lang_protect_cleanup_actions
returns non-null, then the language requires that the exception path out
of a try_finally be treated specially. To wit: the code within the
@@ -703,8 +720,10 @@ honor_protect_cleanup_actions (struct le
if (!finally_may_fallthru && !protect_cleanup_actions)
return;
- /* Duplicate the FINALLY block. */
- finally = lhd_unsave_expr_now (finally);
+ /* Duplicate the FINALLY block. Only need to do this for try-finally,
+ and not for cleanups. */
+ if (this_state)
+ finally = lower_try_finally_dup_block (finally, outer_state);
/* Resume execution after the exception. Adding this now lets
lower_eh_filter not add unnecessary gotos, as it is clear that
@@ -918,7 +937,7 @@ lower_try_finally_copy (struct leh_state
if (tf->may_fallthru)
{
- x = lhd_unsave_expr_now (finally);
+ x = lower_try_finally_dup_block (finally, state);
lower_eh_constructs_1 (state, &x);
tsi_link_chain_after (&i, x, TSI_CHAIN_END);
@@ -933,7 +952,7 @@ lower_try_finally_copy (struct leh_state
x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
tsi_link_after (&i, x, TSI_NEW_STMT);
- x = lhd_unsave_expr_now (finally);
+ x = lower_try_finally_dup_block (finally, state);
lower_eh_constructs_1 (state, &x);
tsi_link_chain_after (&i, x, TSI_CHAIN_END);
@@ -979,7 +998,7 @@ lower_try_finally_copy (struct leh_state
x = build1 (LABEL_EXPR, void_type_node, lab);
tsi_link_after (&i, x, TSI_NEW_STMT);
- x = lhd_unsave_expr_now (finally);
+ x = lower_try_finally_dup_block (finally, state);
lower_eh_constructs_1 (state, &x);
tsi_link_chain_after (&i, x, TSI_CHAIN_END);