aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-08 15:31:20 -0500
committerJason Merrill <jason@gcc.gnu.org>2020-01-08 15:31:20 -0500
commit10d2f801f472931137deae1714d5b690c1862037 (patch)
treef13bc24987acc7188124e8414df9cc31ed103b00
parentcd3ca6cb1129b1e80b5b048a59aa3a0c387c2413 (diff)
downloadgcc-10d2f801f472931137deae1714d5b690c1862037.zip
gcc-10d2f801f472931137deae1714d5b690c1862037.tar.gz
gcc-10d2f801f472931137deae1714d5b690c1862037.tar.bz2
PR c++/91369 - constexpr destructor and member initializer.
Previously it didn't matter whether we looked through a TARGET_EXPR in constexpr evaluation, but now that we have constexpr destructors it does. On IRC I mentioned the idea of clearing TARGET_EXPR_CLEANUP in digest_nsdmi_init, but since this initialization is expressed by an INIT_EXPR, it's better to handle all INIT_EXPR, not just those for a member initializer. * constexpr.c (cxx_eval_store_expression): Look through TARGET_EXPR when not preevaluating. From-SVN: r280018
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C19
3 files changed, 31 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c650fde..7aacbe2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2020-01-08 Jason Merrill <jason@redhat.com>
+ PR c++/91369 - constexpr destructor and member initializer.
+ * constexpr.c (cxx_eval_store_expression): Look through TARGET_EXPR
+ when not preevaluating.
+
+2020-01-08 Jason Merrill <jason@redhat.com>
+
* constexpr.c (cxx_eval_call_expression): Remove DECL_BY_REFERENCE
support.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 806d3ab..5fe6d02 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4577,6 +4577,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
}
new_ctx.ctor = *valp;
new_ctx.object = target;
+ /* Avoid temporary materialization when initializing from a TARGET_EXPR.
+ We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
+ expansion of those trees uses ctx instead. */
+ if (TREE_CODE (init) == TARGET_EXPR)
+ if (tree tinit = TARGET_EXPR_INITIAL (init))
+ init = tinit;
init = cxx_eval_constant_expression (&new_ctx, init, false,
non_constant_p, overflow_p);
if (ctors->is_empty())
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C
new file mode 100644
index 0000000..500a324
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C
@@ -0,0 +1,19 @@
+// PR c++/91369
+// { dg-do compile { target c++2a } }
+
+struct S {
+ constexpr S (int* i) : s{i} {}
+ constexpr ~S () { delete s; }
+ int *s;
+};
+
+struct T { S t = { new int }; };
+
+constexpr auto
+foo ()
+{
+ T b;
+ return true;
+}
+
+static_assert (foo ());