diff mbox

C++ PATCH for c++/67813 (wrong constexpr result)

Message ID 562A9E83.6060004@redhat.com
State New
Headers show

Commit Message

Jason Merrill Oct. 23, 2015, 8:54 p.m. UTC
My patch for 66450 improved a previous problem with clobbering an 
existing value for an aggregate, but we still had the problem that the 
value in the hash table for the object was different from the value in 
ctx->ctor, so changing one didn't update the other.  This patch makes 
sure they're in sync.

Tested x86_64-pc-linux-gnu, applying to trunk and 5.
diff mbox

Patch

commit 7ce7d43552bf06fb82220a7c00635ba05e8144c7
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Oct 22 20:35:44 2015 -1000

    	PR c++/67813
    	* constexpr.c (cxx_eval_store_expression): Always use *valp if
    	set.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 3d682fd..ebca411 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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
index 0000000..ce0c12d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-copy1.C
@@ -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);