blob: 4698ab717d225b2f645f14425afb9e00375ab153 [file] [log] [blame]
// PR middle-end/59470
// { dg-do run }
// { dg-options "-O2 -fstack-protector" }
// { dg-additional-options "-fPIC" { target fpic } }
// { dg-require-effective-target fstack_protector }
struct A
{
int a1;
A () throw () : a1 (0) {}
};
struct B
{
unsigned int b1 () throw ();
};
__attribute__((noinline, noclone)) unsigned int
B::b1 () throw ()
{
asm volatile ("" : : : "memory");
return 0;
}
struct C
{
const A **c1;
void c2 (const A *, unsigned int);
};
__attribute__((noinline, noclone)) void
C::c2 (const A *, unsigned int)
{
asm volatile ("" : : : "memory");
}
struct D
{
C *d1;
};
struct E
{
int e1;
int e2;
D e3;
};
struct F
{
virtual int f1 (const char * s, int n);
};
struct G
{
F *g1;
bool g2;
G & g3 (const char * ws, int len)
{
if (__builtin_expect (!g2, true)
&& __builtin_expect (this->g1->f1 (ws, len) != len, false))
g2 = true;
return *this;
}
};
struct H : public A
{
const char *h1;
unsigned int h2;
bool h3;
const char *h4;
char h5;
char h6;
char h7[31];
bool h8;
H () : h1 (0), h2 (0), h4 (0), h5 (0), h6 (0), h8 (false) {}
void h9 (const D &) __attribute__((noinline, noclone));
};
void
H::h9 (const D &)
{
h3 = true;
__builtin_memset (h7, 0, sizeof (h7));
asm volatile ("" : : : "memory");
};
B b;
inline const H *
foo (const D &x)
{
const unsigned int i = b.b1 ();
const A **j = x.d1->c1;
if (!j[i])
{
H *k = 0;
try
{
k = new H;
k->h9 (x);
}
catch (...)
{
}
x.d1->c2 (k, i);
}
return static_cast <const H *>(j[i]);
}
__attribute__((noinline, noclone)) int
bar (char *x, unsigned long v, const char *y, int z, bool w)
{
asm volatile ("" : : "r" (x), "r" (v), "r" (y) : "memory");
asm volatile ("" : : "r" (z), "r" (w) : "memory");
return 8;
}
__attribute__((noinline, noclone)) void
baz (void *z, const char *g, unsigned int h, char s, E &e, char *n, char *c, int &l)
{
asm volatile ("" : : "r" (z), "r" (g), "r" (h) : "memory");
asm volatile ("" : : "r" (s), "r" (&e), "r" (n) : "memory");
asm volatile ("" : : "r" (c), "r" (&l) : "memory");
if (n == c)
__builtin_abort ();
int i = 0;
asm ("" : "+r" (i));
if (i == 0)
__builtin_exit (0);
}
__attribute__((noinline, noclone)) G
test (void *z, G s, E &x, char, long v)
{
const D &d = x.e3;
const H *h = foo (d);
const char *q = h->h7;
const int f = x.e2;
const int i = 5 * sizeof (long);
char *c = static_cast <char *>(__builtin_alloca (i));
const int b = f & 74;
const bool e = (b != 64 && b != 8);
const unsigned long u = ((v > 0 || !e) ? (unsigned long) v : -(unsigned long) v);
int l = bar (c + i, u, q, f, e);
c += i - l;
if (h->h3)
{
char *c2 = static_cast <char *>(__builtin_alloca ((l + 1) * 2));
baz (z, h->h1, h->h2, h->h6, x, c2 + 2, c, l);
c = c2 + 2;
}
if (__builtin_expect (e, true))
{
}
else if ((f & 4096) && v)
{
{
const bool m = f & 176;
*--c = q[m];
*--c = q[1];
}
}
const int w = x.e1;
if (w > l)
{
char * c3 = static_cast <char *>(__builtin_alloca (w));
c = c3;
}
return s.g3 (c, l);
}
int
main ()
{
H h;
const A *j[1];
C c;
G g;
E e;
h.h9 (e.e3);
j[0] = &h;
c.c1 = j;
e.e3.d1 = &c;
test (0, g, e, 0, 0);
__builtin_abort ();
}