aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C43
3 files changed, 50 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ec99120..49ca2f2 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2016-02-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/69995
+ * constexpr.c (cxx_eval_store_expression): Unshare init.
+
2016-02-26 Jason Merrill <jason@redhat.com>
PR c++/69958
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 8d9168c..5e35940 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2925,6 +2925,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
init = cxx_eval_constant_expression (&new_ctx, init, false,
non_constant_p, overflow_p);
+ /* Don't share a CONSTRUCTOR that might be changed later. */
+ init = unshare_expr (init);
if (target == object)
{
/* The hash table might have moved since the get earlier. */
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C
new file mode 100644
index 0000000..8cea41a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-array3.C
@@ -0,0 +1,43 @@
+// PR c++/69995
+// { dg-do compile { target c++14 } }
+
+#define assert(X) static_assert((X),#X)
+
+#define CONSTEXPR constexpr
+
+template <typename T, unsigned long Size>
+struct array {
+ T elems_[Size];
+
+ constexpr T const& operator[](unsigned long n) const
+ { return elems_[n]; }
+
+ constexpr T& operator[](unsigned long n)
+ { return elems_[n]; }
+};
+
+template <typename T>
+CONSTEXPR void my_swap(T& a, T& b) {
+ T tmp = a;
+ a = b;
+ b = tmp;
+}
+
+CONSTEXPR auto rotate2() {
+ array<array<int, 2>, 2> result{};
+ array<int, 2> a{{0, 1}};
+
+ result[0] = a;
+ my_swap(a[0], a[1]);
+ result[1] = a;
+
+ return result;
+}
+
+int main() {
+ CONSTEXPR auto indices = rotate2();
+ assert(indices[0][0] == 0);
+ assert(indices[0][1] == 1);
+ assert(indices[1][0] == 1);
+ assert(indices[1][1] == 0);
+}