aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-12-20 11:06:27 -0500
committerJason Merrill <jason@redhat.com>2023-12-20 12:31:07 -0500
commit02c0b49798228d777610f898cd9d63ebec43656d (patch)
tree0b0c9eaef863cace223f895163e0215917a2ee49 /gcc
parent8dfc52a75d4d6c8be1c61b4aa831b1812b14a10e (diff)
downloadgcc-02c0b49798228d777610f898cd9d63ebec43656d.zip
gcc-02c0b49798228d777610f898cd9d63ebec43656d.tar.gz
gcc-02c0b49798228d777610f898cd9d63ebec43656d.tar.bz2
c++: throwing dtor and empty try [PR113088]
maybe_splice_retval_cleanup assumed that the function body can't be empty if there's a throwing cleanup, but when I added cleanups to try blocks in r12-6333-gb10e031458d541 I didn't adjust that assumption. PR c++/113088 PR c++/33799 gcc/cp/ChangeLog: * except.cc (maybe_splice_retval_cleanup): Handle an empty block. gcc/testsuite/ChangeLog: * g++.dg/eh/return2.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/except.cc8
-rw-r--r--gcc/testsuite/g++.dg/eh/return2.C26
2 files changed, 32 insertions, 2 deletions
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 7208c08..e4ed277 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -1357,9 +1357,13 @@ maybe_splice_retval_cleanup (tree compound_stmt, bool is_try)
return;
/* Skip past other decls, they can't contain a return. */
- while (TREE_CODE (tsi_stmt (iter)) == DECL_EXPR)
+ while (!tsi_end_p (iter)
+ && TREE_CODE (tsi_stmt (iter)) == DECL_EXPR)
tsi_next (&iter);
- gcc_assert (!tsi_end_p (iter));
+
+ if (tsi_end_p (iter))
+ /* Nothing to wrap. */
+ return;
/* Wrap the rest of the STATEMENT_LIST in a CLEANUP_STMT. */
tree stmts = NULL_TREE;
diff --git a/gcc/testsuite/g++.dg/eh/return2.C b/gcc/testsuite/g++.dg/eh/return2.C
new file mode 100644
index 0000000..b467d74
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/return2.C
@@ -0,0 +1,26 @@
+// PR c++/113088
+
+#if __cplusplus >= 201103L
+#define THROWS noexcept(false)
+#else
+#define THROWS
+#endif
+
+struct X {
+ ~X() {}
+};
+
+struct Y {
+ ~Y() THROWS {}
+};
+
+X foo() {
+ try {
+ return X();
+ } catch (...) {
+ Y();
+ return X();
+ }
+
+ try { } catch (...) { }
+}