On Thu, Dec 12, 2013 at 10:59:01AM -0500, Vladimir Makarov wrote: > The following patch fixes > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59470 > > Committed as rev. 205930 for trunk and 205929 for gcc-4.8 branch. > > Jakub is doing reg testing but I am sure the results will be not > worse as the patch is quite safe IMO. > > 2013-12-12 Vladimir Makarov <vmaka...@redhat.com> > > PR middle-end/59470 > * lra-coalesce.c (lra_coalesce): Invalidate inheritance pseudo > values if necessary.
Thanks, I've committed corresponding testcase for it, also to trunk/4.8. 2013-12-12 Jakub Jelinek <ja...@redhat.com> PR middle-end/59470 * g++.dg/opt/pr59470.C: New test. --- gcc/testsuite/g++.dg/opt/pr59470.C.jj 2013-12-12 13:49:57.532341140 +0100 +++ gcc/testsuite/g++.dg/opt/pr59470.C 2013-12-12 13:52:56.879399925 +0100 @@ -0,0 +1,188 @@ +// 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 (); +} Jakub