]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/91369 - constexpr destructor and member initializer.
authorJason Merrill <jason@redhat.com>
Wed, 8 Jan 2020 20:31:20 +0000 (15:31 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 8 Jan 2020 20:31:20 +0000 (15:31 -0500)
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

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp2a/constexpr-new10.C [new file with mode: 0644]

index c650fdeb5900d1192fac0d778f29b724bf56d904..7aacbe2334b67e4083c9060c8a0e80d0fdd77734 100644 (file)
@@ -1,3 +1,9 @@
+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
index 806d3ab2cffbe520949884f7522c4da0b2250d41..5fe6d0277b6041ba54f4dcb858f5190342d21b56 100644 (file)
@@ -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 (file)
index 0000000..500a324
--- /dev/null
@@ -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 ());