re PR c++/84808 (ICE with constexpr and array)
authorJakub Jelinek <jakub@redhat.com>
Mon, 12 Mar 2018 23:40:20 +0000 (00:40 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 12 Mar 2018 23:40:20 +0000 (00:40 +0100)
PR c++/84808
* constexpr.c (find_array_ctor_elt): Don't use elt reference after
first potential CONSTRUCTOR_ELTS reallocation.  Convert dindex to
sizetype.  Formatting fixes.

* g++.dg/cpp1y/constexpr-84808.C: New test.

From-SVN: r258471

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

index e2373b20064f5640ff8db68ad38585f86382bdce..9b5f0c36663b9ccf8a9abda06753c2fecfee5a8d 100644 (file)
@@ -1,3 +1,10 @@
+2018-03-13  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/84808
+       * constexpr.c (find_array_ctor_elt): Don't use elt reference after
+       first potential CONSTRUCTOR_ELTS reallocation.  Convert dindex to
+       sizetype.  Formatting fixes.
+
 2018-03-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/84355 - ICE with deduction for member class template.
index 2c5a71f3ee5635e63fb3457694d94ff2c2909a49..05a1cb64d61e2c6c84b27a564ddd8ae0ddb31326 100644 (file)
@@ -2194,9 +2194,9 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
      that the same is true of the other elements and index directly.  */
   if (end > 0)
     {
-      tree cindex = (*elts)[end-1].index;
+      tree cindex = (*elts)[end - 1].index;
       if (TREE_CODE (cindex) == INTEGER_CST
-         && compare_tree_int (cindex, end-1) == 0)
+         && compare_tree_int (cindex, end - 1) == 0)
        {
          if (i < end)
            return i;
@@ -2225,6 +2225,8 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
              constructor_elt e;
              tree lo = TREE_OPERAND (idx, 0);
              tree hi = TREE_OPERAND (idx, 1);
+             tree value = elt.value;
+             dindex = fold_convert (sizetype, dindex);
              if (tree_int_cst_lt (lo, dindex))
                {
                  /* There are still some lower elts; shorten the range.  */
@@ -2238,7 +2240,7 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
                  /* Append the element we want to insert.  */
                  ++middle;
                  e.index = dindex;
-                 e.value = unshare_constructor (elt.value);
+                 e.value = unshare_constructor (value);
                  vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
                }
              else
@@ -2254,8 +2256,8 @@ find_array_ctor_elt (tree ary, tree dindex, bool insert = false)
                    e.index = hi;
                  else
                    e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
-                 e.value = unshare_constructor (elt.value);
-                 vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle+1, e);
+                 e.value = unshare_constructor (value);
+                 vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
                }
            }
          return middle;
index da617c7e01bc7fa00043f2994e8af088271ebd47..367a269d43709b08e704ea011f4bd681f9f057c1 100644 (file)
@@ -1,5 +1,8 @@
 2018-03-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c++/84808
+       * g++.dg/cpp1y/constexpr-84808.C: New test.
+
        PR c++/84704
        * g++.dg/debug/pr84704.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-84808.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-84808.C
new file mode 100644 (file)
index 0000000..2f0eeac
--- /dev/null
@@ -0,0 +1,27 @@
+// PR c++/84808
+// { dg-do compile { target c++14 } }
+
+struct A { int i; constexpr A () : i() {} };
+struct B { A a[24]; };
+
+constexpr int
+foo (int n)
+{
+  B b;
+  ++b.a[n + 20].i;
+  ++b.a[n + 18].i;
+  ++b.a[n + 16].i;
+  ++b.a[n + 14].i;
+  ++b.a[n + 12].i;
+  ++b.a[n + 10].i;
+  ++b.a[n + 8].i;
+  ++b.a[n + 6].i;
+  ++b.a[n + 4].i;
+  ++b.a[n + 2].i;
+  ++b.a[n].i;
+  return b.a[2].i + b.a[4].i + b.a[6].i + b.a[8].i + b.a[10].i
+        + b.a[12].i + b.a[14].i + b.a[16].i + b.a[18].i + b.a[20].i + b.a[22].i;
+}
+
+constexpr int i = foo (2);
+static_assert (i == 11, "");