aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2018-03-02 20:27:46 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-03-02 20:27:46 +0000
commit74f8705ebe6ebf42bcfb46cf1c9a26a5ab3bace8 (patch)
treea0f91afc6bbf3b1c8e6c28f30a34ed6d42991a56
parentb2353e5931b1c06053d35c13b9e03f62aca0866c (diff)
downloadgcc-74f8705ebe6ebf42bcfb46cf1c9a26a5ab3bace8.zip
gcc-74f8705ebe6ebf42bcfb46cf1c9a26a5ab3bace8.tar.gz
gcc-74f8705ebe6ebf42bcfb46cf1c9a26a5ab3bace8.tar.bz2
re PR c++/84578 (ICE with flexible array member and constexpr)
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
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/constexpr.c63
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/flexary29.C12
4 files changed, 58 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1164342..6920109 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 39e6cdfb..27f841d 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 622447f..0244231 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..a696fd9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary29.C
@@ -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;