This patch adds support for checking bounds of SVE ACLE vector initialization constructors. It also adds support to construct vector constant from init constructors.
gcc/ChangeLog: * c/c-typeck.cc (process_init_element): Add check to restrict constructor length to the minimum vector length allowed. * tree.cc (build_vector_from_ctor): Add support to construct VLA vector constants from init constructors. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/acle/general-c/sizeless-1.c: Update test to test initialize error. * gcc.target/aarch64/sve/acle/general-c/sizeless-2.c: Likewise. --- gcc/c/c-typeck.cc | 15 ++++++++++----- .../aarch64/sve/acle/general-c/sizeless-1.c | 1 + .../aarch64/sve/acle/general-c/sizeless-2.c | 1 + gcc/tree.cc | 16 +++++++++++----- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 94959f7b8ad..7742b443780 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -11968,13 +11968,18 @@ retry: { tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); - /* Do a basic check of initializer size. Note that vectors - may not always have a fixed size derived from their type. */ - if (known_lt (tree_to_poly_uint64 (constructor_max_index), + /* Do a basic check of initializer size. Note that vectors + may not always have a fixed size derived from their type. */ + if (maybe_lt (tree_to_poly_uint64 (constructor_max_index), tree_to_poly_uint64 (constructor_index))) { - pedwarn_init (loc, 0, - "excess elements in vector initializer"); + /* Diagose VLA out-of-bounds as errors. */ + if (tree_to_poly_uint64 (constructor_max_index).is_constant()) + pedwarn_init (loc, 0, + "excess elements in vector initializer"); + else + error_init (loc, "excess elements in vector initializer"); + break; } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c index f6823a498ab..20eecdad767 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c @@ -69,6 +69,7 @@ statements (int n) int initi_a = sve_sc1; /* { dg-error {incompatible types when initializing type 'int' using type 'svint8_t'} } */ int initi_b = { sve_sc1 }; /* { dg-error {incompatible types when initializing type 'int' using type 'svint8_t'} } */ + svint32_t init_sve_vc1 = { 0, 1, 2, 3, 4 }; /* { dg-error {excess elements in vector initializer} } */ /* Compound literals. */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c index 63a2d7130e1..d3eb8a3727f 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c @@ -69,6 +69,7 @@ statements (int n) int initi_a = sve_sc1; /* { dg-error {incompatible types when initializing type 'int' using type 'svint8_t'} } */ int initi_b = { sve_sc1 }; /* { dg-error {incompatible types when initializing type 'int' using type 'svint8_t'} } */ + svint32_t init_sve_vc1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; /* { dg-warning {excess elements in vector initializer} } */ /* Compound literals. */ diff --git a/gcc/tree.cc b/gcc/tree.cc index b4c059d3b0d..0c524be4a9a 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -2072,12 +2072,18 @@ build_vector_from_ctor (tree type, const vec<constructor_elt, va_gc> *v) if (vec_safe_length (v) == 0) return build_zero_cst (type); - unsigned HOST_WIDE_INT idx, nelts; + unsigned HOST_WIDE_INT idx, nelts, step = 1; tree value; - /* We can't construct a VECTOR_CST for a variable number of elements. */ - nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); - tree_vector_builder vec (type, nelts, 1); + /* If the vector is a VLA, build a VLA constant vector. */ + if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts)) + { + nelts = constant_lower_bound (TYPE_VECTOR_SUBPARTS (type)); + gcc_assert (vec_safe_length (v) <= nelts); + step = 2; + } + + tree_vector_builder vec (type, nelts, step); FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) { if (TREE_CODE (value) == VECTOR_CST) @@ -2090,7 +2096,7 @@ build_vector_from_ctor (tree type, const vec<constructor_elt, va_gc> *v) else vec.quick_push (value); } - while (vec.length () < nelts) + while (vec.length () < nelts * step) vec.quick_push (build_zero_cst (TREE_TYPE (type))); return vec.build (); -- 2.25.1