From: rth Date: Tue, 16 Mar 2010 23:02:35 +0000 (+0000) Subject: PR middle-end/43365 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=fa5d8988596ba8af49805f52faea2419fe3eaba2 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157499 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a160365d8f9..6d39e6d2dcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-03-16 Richard Henderson + + 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. + 2010-03-16 Aldy Hernandez * graphite-sese-to-poly.c (split_reduction_stmt): Skip debug diff --git a/gcc/testsuite/g++.dg/eh/pr43365.C b/gcc/testsuite/g++.dg/eh/pr43365.C new file mode 100644 index 00000000000..32346d5018c --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/pr43365.C @@ -0,0 +1,30 @@ +extern "C" void abort(); + +class Counter +{ +public: + static int count; + ~Counter() { count += 1; } +}; + +int Counter::count = 0; + +void func() +{ + Counter c; + + try { + throw 1; + } + catch (const int&) { + return; + } +} + +int main() +{ + func(); + if (Counter::count != 1) + abort(); + return 0; +} 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; }