diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-22 04:53:33 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-01-22 04:53:33 +0000 |
commit | 0bc060a49d7ac66f72e93cc080abcc9e2175f55c (patch) | |
tree | 1cf758304e987f9c212d745d72e58a7eefe2e85f /gcc/tree-eh.c | |
parent | c1c1e9eb1459db95f3045b78b102b2722ba38b70 (diff) | |
download | gcc-0bc060a49d7ac66f72e93cc080abcc9e2175f55c.tar.gz |
PR c++/34196
* tree.h (TRY_CATCH_IS_CLEANUP): New macro.
* cp/decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP.
* tree-eh.c (honor_protect_cleanup_actions): Strip TRY_CATCH_EXPR
if it is set.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131710 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-eh.c')
-rw-r--r-- | gcc/tree-eh.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 71d3d941b79..44d5a6d59de 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -840,6 +840,23 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, if (this_state) finally = lower_try_finally_dup_block (finally, outer_state); + /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP + set, the handler of the TRY_CATCH_EXPR is another cleanup which ought + to be in an enclosing scope, but needs to be implemented at this level + to avoid a nesting violation (see wrap_temporary_cleanups in + cp/decl.c). Since it's logically at an outer level, we should call + terminate before we get to it, so strip it away before adding the + MUST_NOT_THROW filter. */ + i = tsi_start (finally); + x = tsi_stmt (i); + if (protect_cleanup_actions + && TREE_CODE (x) == TRY_CATCH_EXPR + && TRY_CATCH_IS_CLEANUP (x)) + { + tsi_link_before (&i, TREE_OPERAND (x, 0), TSI_SAME_STMT); + tsi_delink (&i); + } + /* Resume execution after the exception. Adding this now lets lower_eh_filter not add unnecessary gotos, as it is clear that we never fallthru from this copy of the finally block. */ |