aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/constexpr.cc4
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C13
3 files changed, 25 insertions, 2 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 87f3a7b..7274c3b 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9363,8 +9363,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case GOTO_EXPR:
{
tree *target = &TREE_OPERAND (t, 0);
- /* Gotos representing break and continue are OK. */
- if (breaks (target) || continues (target))
+ /* Gotos representing break, continue and cdtor return are OK. */
+ if (breaks (target) || continues (target) || returns (target))
{
*jump_target = *target;
return true;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C
new file mode 100644
index 0000000..4fa78a3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-104513.C
@@ -0,0 +1,10 @@
+// PR c++/104513
+// { dg-do compile { target c++14 } }
+
+struct A {
+ int a1;
+ short a2, a3;
+ long a4;
+ constexpr A() : a1(42), a2(42), a3(42), a4(42) { return; }
+};
+constexpr A a;
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C
new file mode 100644
index 0000000..19f9099b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor12.C
@@ -0,0 +1,13 @@
+// PR c++/104513
+// { dg-do compile { target c++20 } }
+
+struct S {
+ constexpr S () : s (nullptr) {}
+ constexpr ~S () { delete s; }
+ int *s;
+};
+struct T : S {
+ constexpr T () : S () {}
+ constexpr ~T () { s = new int (42); return; }
+};
+constexpr T t;