]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/69995 ([C++14] Invalid result when evaluating constexpr function)
authorJason Merrill <jason@redhat.com>
Mon, 29 Feb 2016 14:25:57 +0000 (09:25 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 29 Feb 2016 14:25:57 +0000 (09:25 -0500)
PR c++/69995
* constexpr.c (cxx_eval_store_expression): Unshare init.

From-SVN: r233810

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

index ec991201009f365a2bd89eaf49c64c020a428dd8..49ca2f273fda63bf5c1d4ea05e7adda667f8c7ba 100644 (file)
@@ -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
index 8d9168c395070ffd180b4066e60b44f0a3ce8288..5e359404c8d64462f64d0bc18fdb37b67c1dbf37 100644 (file)
@@ -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 (file)
index 0000000..8cea41a
--- /dev/null
@@ -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);
+}