Hi!

This function has changed last year to support embedded VECTOR_CSTs in the
ctor elements.  Before that change, there was no pos var and idx used to
match exactly the indices in the new vector, but if there is any VECTOR_CST,
it will fill in more positions.
Unfortunately, the final loop which zeros in any positions not filled in yet
has not changed, which is wrong for the case when there were any
VECTOR_CSTs.  E.g. on the testcase, we have a V16HImode type ctor which
contains two V8HImode VECTOR_CSTs (full of zeros).  Each of them fills in
8 positions, so the final loop shouldn't add anything, but as idx at that
point is 2, it will add further 14 elements, resulting in alloca
buffer overflow.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-02-23  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/69915
        * tree.c (build_vector_from_ctor): Fix handling of VECTOR_CST
        elements.

        * gcc.dg/pr69915.c: New test.

--- gcc/tree.c.jj       2016-02-08 18:39:17.000000000 +0100
+++ gcc/tree.c  2016-02-23 15:50:03.566700694 +0100
@@ -1749,7 +1749,7 @@ build_vector_from_ctor (tree type, vec<c
       else
        vec[pos++] = value;
     }
-  for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
+  while (pos < TYPE_VECTOR_SUBPARTS (type))
     vec[pos++] = build_zero_cst (TREE_TYPE (type));
 
   return build_vector (type, vec);
--- gcc/testsuite/gcc.dg/pr69915.c.jj   2016-02-23 16:02:09.825732486 +0100
+++ gcc/testsuite/gcc.dg/pr69915.c      2016-02-23 16:01:47.000000000 +0100
@@ -0,0 +1,15 @@
+/* PR middle-end/69915 */
+/* { dg-do compile } */
+/* { dg-options "-O -ftracer" } */
+
+typedef unsigned short V __attribute__ ((vector_size (32)));
+
+unsigned
+foo (unsigned x, unsigned c, V *p)
+{
+  V v = *p;
+  if (c < 360)
+    v = (V) { 0 };
+  v *= (V) { x };
+  return v[1];
+}

        Jakub

Reply via email to