aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/except.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-06-06 15:31:23 -0400
committerJason Merrill <jason@redhat.com>2023-06-06 21:30:31 -0400
commit08cea4e56a094ff9cc7c65fdc9ce8c4d7aff64be (patch)
tree02ed204b5c66f3d0d84d29756d18cdc95990c47b /gcc/cp/except.cc
parent0fa9495553e0e0f4ceb764880b5bdd8ade197382 (diff)
downloadgcc-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.cc25
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);