summaryrefslogtreecommitdiff
path: root/gcc/tree-eh.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2010-03-16 16:02:35 -0700
committerRichard Henderson <rth@gcc.gnu.org>2010-03-16 16:02:35 -0700
commite19d1f06837cc6fa1a6ee2540b4ccb572db05bad (patch)
tree1ada8b4322cb58084937c2086ecd64394a1249a7 /gcc/tree-eh.c
parent7ebb824234a5ea9a45c53186494d6273d46f6c84 (diff)
downloadgcc-e19d1f06837cc6fa1a6ee2540b4ccb572db05bad.tar.gz
re PR middle-end/43365 (Destructor not called when returning in exception handler)
PR middle-end/43365 * tree-eh.c (replace_goto_queue): Also replace in the eh_seq. (lower_try_finally): Save and restore eh_seq around the expansion of the try-finally. From-SVN: r157499
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r--gcc/tree-eh.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 5ae47f0c10f..a1aca981d6f 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -564,6 +564,7 @@ replace_goto_queue (struct leh_tf_state *tf)
if (tf->goto_queue_active == 0)
return;
replace_goto_queue_stmt_list (tf->top_p_seq, tf);
+ replace_goto_queue_stmt_list (eh_seq, tf);
}
/* Add a new record to the goto queue contained in TF. NEW_STMT is the
@@ -644,7 +645,6 @@ record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label)
labels. */
new_stmt = stmt;
record_in_goto_queue (tf, new_stmt, index, true);
-
}
/* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
@@ -1531,6 +1531,7 @@ lower_try_finally (struct leh_state *state, gimple tp)
struct leh_tf_state this_tf;
struct leh_state this_state;
int ndests;
+ gimple_seq old_eh_seq;
/* Process the try block. */
@@ -1547,6 +1548,9 @@ lower_try_finally (struct leh_state *state, gimple tp)
this_state.ehp_region = state->ehp_region;
this_state.tf = &this_tf;
+ old_eh_seq = eh_seq;
+ eh_seq = NULL;
+
lower_eh_constructs_1 (&this_state, gimple_try_eval(tp));
/* Determine if the try block is escaped through the bottom. */
@@ -1602,6 +1606,20 @@ lower_try_finally (struct leh_state *state, gimple tp)
if (this_tf.goto_queue_map)
pointer_map_destroy (this_tf.goto_queue_map);
+ /* If there was an old (aka outer) eh_seq, append the current eh_seq.
+ If there was no old eh_seq, then the append is trivially already done. */
+ if (old_eh_seq)
+ {
+ if (eh_seq == NULL)
+ eh_seq = old_eh_seq;
+ else
+ {
+ gimple_seq new_eh_seq = eh_seq;
+ eh_seq = old_eh_seq;
+ gimple_seq_add_seq(&eh_seq, new_eh_seq);
+ }
+ }
+
return this_tf.top_p_seq;
}