re PR c++/84578 (ICE with flexible array member and constexpr)
authorMarek Polacek <polacek@redhat.com>
Fri, 2 Mar 2018 20:27:46 +0000 (20:27 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 2 Mar 2018 20:27:46 +0000 (20:27 +0000)
PR c++/84578
* constexpr.c (get_array_or_vector_nelts): New.
(cxx_eval_array_reference): Use it.
(cxx_eval_vec_init_1): Likewise.
(cxx_eval_store_expression): Likewise.

* g++.dg/ext/flexary29.C: New test.

From-SVN: r258156

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

index 1164342..6920109 100644 (file)
@@ -1,3 +1,11 @@
+2018-03-02  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/84578
+       * constexpr.c (get_array_or_vector_nelts): New.
+       (cxx_eval_array_reference): Use it.
+       (cxx_eval_vec_init_1): Likewise.
+       (cxx_eval_store_expression): Likewise.
+
 2018-03-02  Jason Merrill  <jason@redhat.com>
 
        * semantics.c (force_paren_expr): Remove redundant test.
index 39e6cdf..27f841d 100644 (file)
@@ -2300,6 +2300,32 @@ diag_array_subscript (const constexpr_ctx *ctx, tree array, tree index)
     }
 }
 
+/* Return the number of elements for TYPE (which is an ARRAY_TYPE or
+   a VECTOR_TYPE).  */
+
+static tree
+get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
+                          bool *non_constant_p, bool *overflow_p)
+{
+  tree nelts;
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      if (TYPE_DOMAIN (type))
+       nelts = array_type_nelts_top (type);
+      else
+       nelts = size_zero_node;
+    }
+  else if (VECTOR_TYPE_P (type))
+    nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
+  else
+    gcc_unreachable ();
+
+  /* For VLAs, the number of elements won't be an integer constant.  */
+  nelts = cxx_eval_constant_expression (ctx, nelts, false,
+                                       non_constant_p, overflow_p);
+  return nelts;
+}
+
 /* Extract element INDEX consisting of CHARS_PER_ELT chars from
    STRING_CST STRING.  */
 
@@ -2379,22 +2405,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
        }
     }
 
-  tree nelts;
-  if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-    {
-      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
-    gcc_unreachable ();
-
-  /* For VLAs, the number of elements won't be an integer constant.  */
-  nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
-                                       overflow_p);
+  tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
+                                         overflow_p);
   VERIFY_CONSTANT (nelts);
   if ((lval
        ? !tree_int_cst_le (index, nelts)
@@ -2895,7 +2907,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
                     bool *non_constant_p, bool *overflow_p)
 {
   tree elttype = TREE_TYPE (atype);
-  unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype));
   verify_ctor_sanity (ctx, atype);
   vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
   bool pre_init = false;
@@ -2924,6 +2935,9 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
       pre_init = true;
     }
 
+  tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
+                                         overflow_p);
+  unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
   for (i = 0; i < max; ++i)
     {
       tree idx = build_int_cst (size_type_node, i);
@@ -3480,19 +3494,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
        case ARRAY_REF:
          tree nelts, ary;
          ary = TREE_OPERAND (probe, 0);
-         if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
-           {
-             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
-           gcc_unreachable ();
-         nelts = cxx_eval_constant_expression (ctx, nelts, false,
-                                               non_constant_p, overflow_p);
+         nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary),
+                                            non_constant_p, overflow_p);
          VERIFY_CONSTANT (nelts);
          gcc_assert (TREE_CODE (nelts) == INTEGER_CST
                      && TREE_CODE (TREE_OPERAND (probe, 1)) == INTEGER_CST);
index 622447f..0244231 100644 (file)
@@ -1,3 +1,8 @@
+2018-03-02  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/84578
+       * g++.dg/ext/flexary29.C: New test.
+
 2018-03-02  Jakub Jelinek  <jakub@redhat.com>
 
        * c-c++-common/Warray-bounds-2.c: Fix a comment typo.
diff --git a/gcc/testsuite/g++.dg/ext/flexary29.C b/gcc/testsuite/g++.dg/ext/flexary29.C
new file mode 100644 (file)
index 0000000..a696fd9
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/84578
+// { dg-do compile { target c++11 } }
+// { dg-options -Wno-pedantic }
+
+struct A
+{
+  constexpr A() : i(), x() {}
+  int i;
+  char x[];
+};
+
+A a;