re PR c++/67813 ([C++14] copy-initialization of object with pointer member fails...
authorJason Merrill <jason@redhat.com>
Fri, 23 Oct 2015 20:57:05 +0000 (16:57 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 23 Oct 2015 20:57:05 +0000 (16:57 -0400)
PR c++/67813
* constexpr.c (cxx_eval_store_expression): Always use *valp if
set.

From-SVN: r229270

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

index 2970ec2cd043ae25875371b36abcb57984116bc7..e3dbe6b7090eb1aefcd1b634c9e4be97f360df4c 100644 (file)
@@ -1,3 +1,9 @@
+2015-10-23  Jason Merrill  <jason@redhat.com>
+
+       PR c++/67813
+       * constexpr.c (cxx_eval_store_expression): Always use *valp if
+       set.
+
 2015-10-22  Jason Merrill  <jason@redhat.com>
 
        * call.c (add_template_conv_candidate): Pass DEDUCE_CALL.
index 3d682fd23f2a01c314ff3be4b5efa9f998eae7c6..ebca411b3eb41d268ff2bc031bf45594b34b1cf2 100644 (file)
@@ -2802,10 +2802,13 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
     {
       /* Create a new CONSTRUCTOR in case evaluation of the initializer
         wants to modify it.  */
-      new_ctx.ctor = build_constructor (type, NULL);
       if (*valp == NULL_TREE)
-       *valp = new_ctx.ctor;
-      CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = no_zero_init;
+       {
+         *valp = new_ctx.ctor = build_constructor (type, NULL);
+         CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = no_zero_init;
+       }
+      else
+       new_ctx.ctor = *valp;
       new_ctx.object = target;
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-copy1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy1.C
new file mode 100644 (file)
index 0000000..ce0c12d
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/67813
+// { dg-do compile { target c++14 } }
+
+struct Ptr {
+  int* p;
+
+  constexpr Ptr(int* p) noexcept : p{p} {}
+  constexpr int& operator*() const {
+    return *p;
+  }
+};
+
+constexpr int f(int& i) {
+  //Ptr first{&i}; // Works.
+  Ptr first = &i;  // Error
+  return *first;
+}
+
+constexpr int g() {
+  int i = 42;
+  return f(i);
+}
+
+#define SA(X) static_assert((X), #X)
+SA(g() == 42);