// PR middle-end/6247 // This testcase was miscompiled on IA-32 because a single stack slot // was used for 2 different variables at the same time. // The function H::h1 was miscompiled. // { dg-do run } // { dg-options "-O2" } extern "C" void abort (void); extern "C" void exit (int); struct A { A () { a = 1; } void a1 () { a++; } bool a2 () { return !--a; } unsigned int a; }; struct B : public A { B () : b (0) { a1 (); } void b1 (); const char *b; }; struct C { C (); C (const C &); ~C () { if (c->a2 ()) { if (c == c0) c0 = 0; c->b1 (); } } C &operator= (const C &); static C c1 (const char *x, int y = -1); C (int, bool); void a2 (); B *c; static B *c0; }; B *C::c0 = __null; template struct D { D (const T& t) : d (t) {} D () {} D *next, *prev; T d; }; template struct E { D *e; E () : e (0) {} E (D *p) : e (p) {} E (const E& x) : e (x.e) {} const T& operator* () const { return e->d; } T& operator* () { return e->d; } bool operator== (const E& x) const { return e == x.e; } bool operator!= (const E& x) const { return e != x.e; } E operator++ (int) { E x = *this; e = e->next; return x; } }; template struct F : public A { F () { f = new D; f->next = f->prev = f; f0 = 0; } ~F () {} D *f; unsigned int f0; F (const F& x) : A () { f = new D; f->next = f->prev = f; f0 = 0; E b (x.f->next); E e (x.f); E i (f); while (b != e) f1 (i, *b++); } E f1 (E x, const T& y) { D *p = new D (y); p->next = x.e; p->prev = x.e->prev; x.e->prev->next = p; x.e->prev = p; f0++; return p; } }; template struct G { E g1 () { g3 (); return E (g->f); } E g2 (const T& x) { g3 (); return g->f1 (g1 (), x); } void g3 () { if (g->a > 1) { g->a2 (); g = new F (*g); } } F* g; }; struct H { virtual ~H () {}; virtual void h1 (); struct I { I () {} I (C r, C p) : i1 (r), i2 (p) {} C i1, i2; }; G h; }; void H::h1 () { h.g2 (I (C::c1 ("s1"), C::c1 ("t"))); h.g2 (I (C::c1 ("s2"), C::c1 ("t"))); h.g2 (I (C::c1 ("s3"), C::c1 ("t"))); } void B::b1 () { } C C::c1 (const char *x, int y) { C z; if (y != -1) abort (); z.c = new B; z.c->b = x; return z; } C::C () : c (__null) { } C::C (const C &x) { c = x.c; c->a1 (); } int main () { H h; h.h.g = new F (); h.h1 (); if (h.h.g->f0 != 3) abort (); D *p; int i; for (i = 0, p = h.h.g->f; i < 4; i++, p = p->next) { if (i == 0 && (p->d.i1.c != __null || p->d.i2.c != __null)) abort (); if (i > 0 && (p->d.i1.c->b[0] != 's' || p->d.i1.c->b[1] != '0' + i || p->d.i1.c->b[2] != '\0' || __builtin_strcmp (p->d.i2.c->b, "t"))) abort (); if (p->prev->next != p) abort (); if (p->next->prev != p) abort (); if (i == 3 && p->next != h.h.g->f) abort (); } exit (0); }