diff options
author | Jason Merrill <jason@redhat.com> | 2023-06-06 15:31:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-06-06 21:30:31 -0400 |
commit | 08cea4e56a094ff9cc7c65fdc9ce8c4d7aff64be (patch) | |
tree | 02ed204b5c66f3d0d84d29756d18cdc95990c47b /gcc/cp/except.cc | |
parent | 0fa9495553e0e0f4ceb764880b5bdd8ade197382 (diff) | |
download | gcc-08cea4e56a094ff9cc7c65fdc9ce8c4d7aff64be.zip gcc-08cea4e56a094ff9cc7c65fdc9ce8c4d7aff64be.tar.gz gcc-08cea4e56a094ff9cc7c65fdc9ce8c4d7aff64be.tar.bz2 |
c++: fix throwing cleanup with label
While looking at PR92407 I noticed that the expectations of
maybe_splice_retval_cleanup weren't being met; an sk_cleanup level was
confusing its attempt to recognize the outer block of the function. And
even if I fixed the detection, it failed to actually wrap the body of the
function because the STATEMENT_LIST it got only had the label, not anything
after it. So I moved the call after poplevel does pop_stmt_list on all the
sk_cleanup levels.
PR c++/33799
gcc/cp/ChangeLog:
* except.cc (maybe_splice_retval_cleanup): Change
recognition of function body and try scopes.
* semantics.cc (do_poplevel): Call it after poplevel.
(at_try_scope): New.
* cp-tree.h (maybe_splice_retval_cleanup): Adjust.
gcc/testsuite/ChangeLog:
* g++.dg/eh/return1.C: Add label cases.
Diffstat (limited to 'gcc/cp/except.cc')
-rw-r--r-- | gcc/cp/except.cc | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index b04eb00..28106da 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -1312,21 +1312,20 @@ maybe_set_retval_sentinel () on throw. */ void -maybe_splice_retval_cleanup (tree compound_stmt) +maybe_splice_retval_cleanup (tree compound_stmt, bool is_try) { - /* If we need a cleanup for the return value, add it in at the same level as + if (!current_function_decl || !cfun + || DECL_CONSTRUCTOR_P (current_function_decl) + || DECL_DESTRUCTOR_P (current_function_decl) + || !current_retval_sentinel) + return; + + /* if we need a cleanup for the return value, add it in at the same level as pushdecl_outermost_localscope. And also in try blocks. */ - const bool function_body - = (current_binding_level->level_chain - && current_binding_level->level_chain->kind == sk_function_parms - /* When we're processing a default argument, c_f_d may not have been - set. */ - && current_function_decl); - - if ((function_body || current_binding_level->kind == sk_try) - && !DECL_CONSTRUCTOR_P (current_function_decl) - && !DECL_DESTRUCTOR_P (current_function_decl) - && current_retval_sentinel) + cp_binding_level *b = current_binding_level; + const bool function_body = b->kind == sk_function_parms; + + if (function_body || is_try) { location_t loc = DECL_SOURCE_LOCATION (current_function_decl); tree_stmt_iterator iter = tsi_start (compound_stmt); |