public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-9988] c++: fix throwing cleanup with label
@ 2023-11-17 0:21 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2023-11-17 0:21 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:65388a996d7dfcdd22ff2d191458699d1cacf254
commit r12-9988-g65388a996d7dfcdd22ff2d191458699d1cacf254
Author: Jason Merrill <jason@redhat.com>
Date: Tue Jun 6 15:31:23 2023 -0400
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.
Diff:
---
gcc/cp/cp-tree.h | 2 +-
gcc/cp/except.cc | 25 ++++++++++++-------------
gcc/cp/semantics.cc | 16 +++++++++++++++-
gcc/testsuite/g++.dg/eh/return1.C | 21 +++++++++++++++++++++
4 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6906b9bfdc8..5b3836422d6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7014,7 +7014,7 @@ extern tree begin_eh_spec_block (void);
extern void finish_eh_spec_block (tree, tree);
extern tree build_eh_type_type (tree);
extern tree cp_protect_cleanup_actions (void);
-extern void maybe_splice_retval_cleanup (tree);
+extern void maybe_splice_retval_cleanup (tree, bool);
extern tree maybe_set_retval_sentinel (void);
extern tree template_parms_to_args (tree);
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 58d8772fc95..ef1d3e8567a 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -1318,21 +1318,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
- 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 (!current_function_decl || !cfun
+ || DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl)
+ || !current_retval_sentinel)
+ return;
- if ((function_body || current_binding_level->kind == sk_try)
- && !DECL_CONSTRUCTOR_P (current_function_decl)
- && !DECL_DESTRUCTOR_P (current_function_decl)
- && current_retval_sentinel)
+ /* 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. */
+ 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);
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index ee0db331f34..5289131e591 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -627,6 +627,17 @@ set_cleanup_locs (tree stmts, location_t loc)
set_cleanup_locs (stmt, loc);
}
+/* True iff the innermost block scope is a try block. */
+
+static bool
+at_try_scope ()
+{
+ cp_binding_level *b = current_binding_level;
+ while (b && b->kind == sk_cleanup)
+ b = b->level_chain;
+ return b && b->kind == sk_try;
+}
+
/* Finish a scope. */
tree
@@ -634,11 +645,14 @@ do_poplevel (tree stmt_list)
{
tree block = NULL;
- maybe_splice_retval_cleanup (stmt_list);
+ bool was_try = at_try_scope ();
if (stmts_are_full_exprs_p ())
block = poplevel (kept_level_p (), 1, 0);
+ /* This needs to come after poplevel merges sk_cleanup statement_lists. */
+ maybe_splice_retval_cleanup (stmt_list, was_try);
+
stmt_list = pop_stmt_list (stmt_list);
/* input_location is the last token of the scope, usually a }. */
diff --git a/gcc/testsuite/g++.dg/eh/return1.C b/gcc/testsuite/g++.dg/eh/return1.C
index ac2225405da..e22d674ae9a 100644
--- a/gcc/testsuite/g++.dg/eh/return1.C
+++ b/gcc/testsuite/g++.dg/eh/return1.C
@@ -33,6 +33,13 @@ X f()
return X(false);
}
+X f2()
+{
+ foo:
+ X x(true);
+ return X(false);
+}
+
X g()
{
return X(true),X(false);
@@ -54,6 +61,16 @@ X i()
return X(false);
}
+X i2()
+{
+ try {
+ foo:
+ X x(true);
+ return X(false);
+ } catch(...) {}
+ return X(false);
+}
+
X j()
{
try {
@@ -84,6 +101,8 @@ int main()
try { f(); }
catch (...) {}
+ try { f2(); } catch (...) {}
+
try { g(); }
catch (...) {}
@@ -93,6 +112,8 @@ int main()
try { i(); }
catch (...) {}
+ try { i2(); } catch (...) {}
+
try { j(); } catch (...) {}
try { k<X>(); } catch (...) {}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-11-17 0:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-17 0:21 [gcc r12-9988] c++: fix throwing cleanup with label Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).