/* PR middle-end/70025 */ /* { dg-do run } */ /* { dg-additional-options "-mtune=z10" { target s390*-*-* } } */ /* { dg-require-effective-target int32plus } */ typedef char (*F) (unsigned long, void *); typedef union { struct A { char a1, a2, a3, a4; unsigned long a5; F a6; void *a7; } b; char c[1]; } B; struct C { const char *c1; unsigned long c2; }; typedef struct D { unsigned long d1; int d2; const char *d3; unsigned long d4, d5; struct C d6[49]; char d7[8]; } E[1]; __attribute__ ((noinline, noclone)) void foo (register E p) { asm volatile ("" : : "r" (p) : "memory"); } __attribute__ ((noinline, noclone)) void bar (register E p) { register unsigned long k = p[0].d1 + 1; register struct C *l = &p[0].d6[p[0].d2]; register const char *m = l->c1; p[0].d1 = k; if (*m == '\0') { register struct A *f = &((B *) m)->b; register unsigned long n = l->c2; register unsigned long o = n + f->a5; if (k < o) { register unsigned long i; register unsigned long q = k + 8; register F a6 = f->a6; register void *a7 = f->a7; if (q > o) q = o; for (i = k; i < q; i++) p[0].d7[i - k] = (*a6) (i - n, a7); p[0].d4 = k; p[0].d3 = p[0].d7; p[0].d5 = q; return; } } while (p[0].d2 > 0 && l[0].c2 != l[-1].c2) { p[0].d2--; l--; } if (p[0].d2 == 0) { p[0].d2 = 0x55555555; return; } p[0].d2--; foo (p); } char baz (unsigned long i, void *j) { if (j != 0) __builtin_abort (); return (char) i; } int main () { struct D p; struct A f; __builtin_memset (&f, 0, sizeof (f)); f.a2 = 4; f.a5 = 13; f.a6 = baz; __builtin_memset (&p, 0, sizeof (p)); p.d6[0].c1 = (const char *) &f; bar (&p); if (p.d4 != 1 || p.d5 != 9 || p.d3 != p.d7) __builtin_abort (); return 0; } /* At -O3 the loop in bar() is vectorized and results in a (possibly unreachable) out-of-bounds store to p.d7[8]: _22(D)->d7[8] = _122; { dg-prune-output "-Wstringop-overflow" } */