aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-copy1.C25
3 files changed, 37 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2970ec2..e3dbe6b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
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);