re PR c++/83993 (ICE: constant not recomputed when ADDR_EXPR changed)
authorJakub Jelinek <jakub@redhat.com>
Wed, 31 Jan 2018 20:45:41 +0000 (21:45 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 31 Jan 2018 20:45:41 +0000 (21:45 +0100)
PR c++/83993
* constexpr.c (diag_array_subscript): Emit different diagnostics
if TYPE_DOMAIN (arraytype) is NULL.
(cxx_eval_array_reference, cxx_eval_store_expression): For arrays
with NULL TYPE_DOMAIN use size_zero_node as nelts.

* g++.dg/init/pr83993-1.C: New test.
* g++.dg/cpp0x/pr83993.C: New test.

From-SVN: r257264

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr83993.C [new file with mode: 0644]
gcc/testsuite/g++.dg/init/pr83993-1.C [new file with mode: 0644]

index ee06ba61546bd1f8043a34d43f3656bed18d05df..c8df8f12f14cc27eb625270defe3425ca04c6676 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/83993
+       * constexpr.c (diag_array_subscript): Emit different diagnostics
+       if TYPE_DOMAIN (arraytype) is NULL.
+       (cxx_eval_array_reference, cxx_eval_store_expression): For arrays
+       with NULL TYPE_DOMAIN use size_zero_node as nelts.
+
 2018-01-31  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/84092
index 0a1944f6dad4e01ada48d8da29bb8cd1c47833bd..087d8d8f4a3d157f726f276effc89bd81ae4f9ef 100644 (file)
@@ -2270,13 +2270,20 @@ diag_array_subscript (const constexpr_ctx *ctx, tree array, tree index)
       tree sidx = fold_convert (ssizetype, index);
       if (DECL_P (array))
        {
-         error ("array subscript value %qE is outside the bounds "
-                "of array %qD of type %qT", sidx, array, arraytype);
+         if (TYPE_DOMAIN (arraytype))
+           error ("array subscript value %qE is outside the bounds "
+                  "of array %qD of type %qT", sidx, array, arraytype);
+         else
+           error ("non-zero array subscript %qE is used with array %qD of "
+                  "type %qT with unknown bounds", sidx, array, arraytype);
          inform (DECL_SOURCE_LOCATION (array), "declared here");
        }
-      else
+      else if (TYPE_DOMAIN (arraytype))
        error ("array subscript value %qE is outside the bounds "
               "of array type %qT", sidx, arraytype);
+      else
+       error ("non-zero array subscript %qE is used with array of type %qT "
+              "with unknown bounds", sidx, arraytype);
     }
 }
 
@@ -2361,7 +2368,12 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
 
   tree nelts;
   if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-    nelts = array_type_nelts_top (TREE_TYPE (ary));
+    {
+      if (TYPE_DOMAIN (TREE_TYPE (ary)))
+       nelts = array_type_nelts_top (TREE_TYPE (ary));
+      else
+       nelts = size_zero_node;
+    }
   else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
     nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
   else
@@ -3445,7 +3457,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
          tree nelts, ary;
          ary = TREE_OPERAND (probe, 0);
          if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-           nelts = array_type_nelts_top (TREE_TYPE (ary));
+           {
+             if (TYPE_DOMAIN (TREE_TYPE (ary)))
+               nelts = array_type_nelts_top (TREE_TYPE (ary));
+             else
+               nelts = size_zero_node;
+           }
          else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
            nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
          else
index 70cba83b6e2a94a6defdacf4851f2b4b8060364c..5feda0b90cfa7ead1b64d912ab279836ac27aaf3 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-31  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/83993
+       * g++.dg/init/pr83993-1.C: New test.
+       * g++.dg/cpp0x/pr83993.C: New test.
+
 2018-01-31  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/84088
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83993.C b/gcc/testsuite/g++.dg/cpp0x/pr83993.C
new file mode 100644 (file)
index 0000000..17b7a64
--- /dev/null
@@ -0,0 +1,49 @@
+// PR c++/83993
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+extern const int a[];
+const int b[5] = { 1, 2, 3, 4, 5 };
+extern const int c[4];
+constexpr const int *d = &a[0];
+constexpr const int *d2 = a;
+constexpr const int *e = &a[1];                // { dg-error "non-zero array subscript '1' is used with array 'a' of type 'const int \\\[\\\]' with unknown bounds" }
+constexpr const int *f = &b[0];
+constexpr const int *f2 = b;
+constexpr const int *g = &b[5];
+constexpr const int *h = &b[6];                // { dg-error "array subscript value '6' is outside the bounds of array 'b' of type 'const int \\\[5\\\]'" }
+constexpr const int *i = &c[0];
+constexpr const int *i2 = c;
+constexpr const int *j = &c[4];
+constexpr const int *k = &c[5];                // { dg-error "array subscript value '5' is outside the bounds of array 'c' of type 'const int \\\[4\\\]'" }
+extern const int l[];
+
+void
+foo ()
+{
+  extern const int l[3];
+  constexpr const int *m = &l[0];
+  constexpr const int *m2 = l;
+  constexpr const int *n = &l[1];
+  static_assert (m == m2, "");
+}
+
+constexpr const int *m = &l[0];
+constexpr const int *m2 = l;
+constexpr const int *n = &l[1];                // { dg-error "non-zero array subscript '1' is used with array 'l' of type 'const int \\\[\\\]' with unknown bounds" }
+static_assert (d == d2 && f == f2 && i == i2 && m == m2, "");
+const int o[] = { 1, 2 };
+constexpr const int *p = &o[0];
+constexpr const int *p2 = o;
+constexpr const int *q = &o[2];
+constexpr const int *r = &o[3];                // { dg-error "array subscript value '3' is outside the bounds of array 'o' of type 'const int \\\[2\\\]'" }
+struct S { char a; char b[]; } s;
+constexpr const char *t = &s.b[0];
+constexpr const char *t2 = s.b;
+constexpr const char *u = &s.b[1];     // { dg-error "non-zero array subscript '1' is used with array of type 'char \\\[\\\]' with unknown bounds" }
+struct V { int a; };
+extern V v[];
+constexpr V *w = &v[0];
+constexpr V *w2 = v;
+constexpr int *x = &v[0].a;
+constexpr int y = a[0];                        // { dg-error "the value of 'a' is not usable in a constant expression" }
diff --git a/gcc/testsuite/g++.dg/init/pr83993-1.C b/gcc/testsuite/g++.dg/init/pr83993-1.C
new file mode 100644 (file)
index 0000000..0499235
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/83993
+// { dg-do compile }
+
+extern const int a[];
+const int *const b = &a[0];
+
+int
+foo ()
+{
+  return b[0];
+}