From: Jason Merrill Date: Mon, 7 May 2018 19:22:35 +0000 (-0400) Subject: PR c++/85618 - ICE with initialized VLA. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1d473b8b9dd499a5e34d6a05d9ef2f4b521d1056;p=gcc.git 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. From-SVN: r260012 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f7969d40c8d..8ab3d36b711 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-05-07 Jason Merrill + + 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. + 2018-05-05 Paolo Carlini * cvt.c (ocp_convert): Early handle the special case of a 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** 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] = {}; + }