]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Fix constructor bounds checking for VLA and construct VLA vector constants
authorTejas Belagod <tejas.belagod@arm.com>
Thu, 5 Sep 2024 09:18:18 +0000 (14:48 +0530)
committerTejas Belagod <tejas.belagod@arm.com>
Fri, 29 Nov 2024 11:33:19 +0000 (17:03 +0530)
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/c/ChangeLog:

* c-typeck.cc (process_init_element): Add check to restrict
constructor length to the minimum vector length allowed.

gcc/ChangeLog:

* 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
gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-1.c
gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/sizeless-2.c
gcc/tree.cc

index 23ce0fc788dcf87603522dea5ab48b6feaf799f8..0189a800c11f52538a7fe599c9daa6be530dea47 100644 (file)
@@ -12083,12 +12083,18 @@ retry:
        {
          tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
 
-        /* Do a basic check of initializer size.  Note that vectors
-           always have a fixed size derived from their type.  */
-         if (tree_int_cst_lt (constructor_max_index, constructor_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;
            }
 
index b0389fa00a85ed115daac933b1908ff11bf7803d..747bac464a56177c7261f2236a32474c8db95cba 100644 (file)
@@ -38,6 +38,8 @@ void ext_consume_sve_sc (svint8_t);
 void ext_consume_varargs (int, ...);
 svint8_t ext_produce_sve_sc ();
 
+extern int bar (void);
+
 /* Main tests for statements and expressions.  */
 
 void
@@ -69,6 +71,17 @@ 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 };
+  svint32_t init_sve_vc2 = { 0, bar () };
+  svint32_t init_sve_vc3 = { bar (), n };
+  svint32_t init_sve_vc4 = { 0, 1, 2, 3 };
+  svint32_t init_sve_vc5 = { 0, 1, bar (), 3 };
+  svint32_t init_sve_vc6 = { 0, 1, 2, 3, 4 }; /* { dg-error {excess elements in vector initializer} } */
+  svint32_t init_sve_vc7 = { 0, 1, 2, 3, bar () }; /* { dg-error {excess elements in vector initializer} } */
+  svint32_t init_sve_vc8 = { 0, 1, 2, 3, 4, 5 }; /* { dg-error {excess elements in vector initializer} } */
+  svint32_t init_sve_vc9 = { 0, bar (), 2, 3, 4, n }; /* { dg-error {excess elements in vector initializer} } */
+
+
 
   /* Compound literals.  */
 
index d16f40b5f2a4dbdd1fb7a2d57cf6c259b6d7b6df..33cd21610eafa2c89f9c3aaa9774f3d2aa489f50 100644 (file)
@@ -38,6 +38,8 @@ void ext_consume_sve_sc (svint8_t);
 void ext_consume_varargs (int, ...);
 svint8_t ext_produce_sve_sc ();
 
+extern int bar (void);
+
 /* Main tests for statements and expressions.  */
 
 void
@@ -69,6 +71,16 @@ 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 };
+  svint32_t init_sve_vc2 = { 0, bar () };
+  svint32_t init_sve_vc3 = { bar (), n };
+  svint32_t init_sve_vc4 = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  svint32_t init_sve_vc5 = { 0, 1, bar (), 3, 4, 5, 6, 7 };
+  svint32_t init_sve_vc6 = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; /* { dg-warning {excess elements in vector initializer} } */
+  svint32_t init_sve_vc7 = { 0, 1, 2, 3, bar (), 5, 6, 7, 8 }; /* { dg-warning {excess elements in vector initializer} } */
+  svint32_t init_sve_vc8 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; /* { dg-warning {excess elements in vector initializer} } */
+  svint32_t init_sve_vc9 = { 0, bar (), 2, 3, 4, 5, 6, 7, 8, 9, n }; /* { dg-warning {excess elements in vector initializer} } */
+
 
   /* Compound literals.  */
 
index 74d13a8d583233c6325f1951be54fe03ba38a5e6..83a03374a3255d8b8e46bfe9da8759fa2964fbf0 100644 (file)
@@ -2084,12 +2084,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)
@@ -2102,7 +2108,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 ();