This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/85618, ICE with initialized VLA
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 7 May 2018 15:22:13 -0400
- Subject: C++ PATCH for c++/85618, ICE with initialized VLA
The fix for 84560 clarified that an array with multiple non-constant
bounds is not an N3639 array of runtime bound, because that proposal
only allowed a single variable bound. But store_init_value was using
array_of_runtime_bound_p to decide whether we need to use
build_vec_init for initialization, which is still necessary for a
multi-dimensional VLA. This patch addresses the issue by introducing
vla_type_p for the broader question.
Tested x86_64-pc-linux-gnu, applying to trunk and 8.
commit 164269694606b6bc077aa2ade1a1d87c471a5462
Author: Jason Merrill <jason@redhat.com>
Date: Mon May 7 12:27:43 2018 -0400
PR c++/85618 - ICE with initialized VLA.
* tree.c (vla_type_p): New.
* typeck2.c (store_init_value, split_nonconstant_init_1): Check it
rather than array_of_runtime_bound_p.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3cd7421ba92..d5ef6d3cf80 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7097,6 +7097,7 @@ extern tree get_target_expr_sfinae (tree, tsubst_flags_t);
extern tree build_cplus_array_type (tree, tree);
extern tree build_array_of_n_type (tree, int);
extern bool array_of_runtime_bound_p (tree);
+extern bool vla_type_p (tree);
extern tree build_array_copy (tree);
extern tree build_vec_init_expr (tree, tree, tsubst_flags_t);
extern void diagnose_non_constexpr_vec_init (tree);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index dbe84c08a8f..313ff9008e4 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1051,8 +1051,10 @@ build_array_of_n_type (tree elt, int n)
return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
}
-/* True iff T is an N3639 array of runtime bound (VLA). These were
- approved for C++14 but then removed. */
+/* True iff T is an N3639 array of runtime bound (VLA). These were approved
+ for C++14 but then removed. This should only be used for N3639
+ specifically; code wondering more generally if something is a VLA should use
+ vla_type_p. */
bool
array_of_runtime_bound_p (tree t)
@@ -1069,6 +1071,23 @@ array_of_runtime_bound_p (tree t)
|| (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)));
}
+/* True iff T is a variable length array. */
+
+bool
+vla_type_p (tree t)
+{
+ for (; t && TREE_CODE (t) == ARRAY_TYPE;
+ t = TREE_TYPE (t))
+ if (tree dom = TYPE_DOMAIN (t))
+ {
+ tree max = TYPE_MAX_VALUE (dom);
+ if (!potential_rvalue_constant_expression (max)
+ || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)))
+ return true;
+ }
+ return false;
+}
+
/* Return a reference type node referring to TO_TYPE. If RVAL is
true, return an rvalue reference type, otherwise return an lvalue
reference type. If a type node exists, reuse it, otherwise create
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 37e78936103..444ebfdcb37 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -611,7 +611,7 @@ split_nonconstant_init_1 (tree dest, tree init)
array_type_p = true;
if ((TREE_SIDE_EFFECTS (init)
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
- || array_of_runtime_bound_p (type))
+ || vla_type_p (type))
{
/* For an array, we only need/want a single cleanup region rather
than one per element. */
@@ -861,7 +861,7 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
will perform the dynamic initialization. */
if (value != error_mark_node
&& (TREE_SIDE_EFFECTS (value)
- || array_of_runtime_bound_p (type)
+ || vla_type_p (type)
|| ! reduced_constant_expression_p (value)))
return split_nonconstant_init (decl, value);
/* If the value is a constant, just put it in DECL_INITIAL. If DECL
diff --git a/gcc/testsuite/g++.dg/ext/vla20.C b/gcc/testsuite/g++.dg/ext/vla20.C
new file mode 100644
index 00000000000..80eae0cde61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vla20.C
@@ -0,0 +1,6 @@
+// PR c++/85618
+// { dg-additional-options "-Wno-vla" }
+
+ void function(int size) {
+ bool myArray[size][size] = {};
+ }