// This testcase was miscompiled on IA-64 to read from unitialized memory // and dereference it. // { dg-do run } // { dg-options "-O2" } struct A { A () { a = 1; } void a1 () { a++; } bool a2 () { return !--a; } unsigned int a; }; struct B {}; template struct C { C () {} C (const T& t) : c (t) {} C *next, *prev; T c; }; template struct D { C *d; D () : d (0) {} D (C *x) : d (x) {} D (const D& x) : d (x.d) {} bool operator!= (const D& x) const { return d != x.d; } const T& operator* () const { return d->c; } D operator++ (int) { D t = *this; d = d->next; return t; } }; template struct E { C *e; E () : e (0) {} E (C *p) : e (p) {} E (const E& x) : e (x.e) {} E (const D& x) : e (x.e) {} bool operator!= (const E& x) const { return e != x.e; } const T& operator* () const { return e->c; } E& operator++ () { e = e->next; return *this; } }; template struct F : public A { C *f; unsigned long f0; F () { f = new C; f->next = f->prev = f; f0 = 0; } F (const F& x) : A () { f = new C; f->next = f->prev = f; f0 = 0; D b (x.f->next), e (x.f), i (f); while (b != e) f1 (i, *b++); } ~F () { C *p = f->next; while (p != f) { C *x = p->next; delete p; p = x; } delete f; } D f1 (D x, const T& y) { C *p = new C (y); p->next = x.d; p->prev = x.d->prev; x.d->prev->next = p; x.d->prev = p; f0++; return p; } }; template struct G { F *g; G () { g = new F; } G (const G& x) { g = x.g; g->a1 (); } ~G () {} G& operator= (const G& x) { x.g->a1 (); g = x.g; return *this; } D g1 () { g4 (); return D (g->f); } E g1 () const { return E (g->f); } E g2 () const { return E (g->f->next); } D g3 (const T& x) { g4 (); return g->f1 (g1 (), x); } void g4 () { if (g->a > 1) { g->a2 (); g = new F (*g); } } G operator+ (const G& x) const { G x2 (*this); for (E i = x.g2 (); i != x.g1 (); ++i) x2.g3 (*i); return x2; } G& operator+= (const G& x) { for (E i = x.g2 (); i != x.g1 (); ++i) g3 (*i); return *this; } }; struct H : public G { H () {} H (const H& x) : G (x) {} H (const G& x) : G (x) {} }; void foo (); int main () { H a = H () + H (); a += H (); H b; b = H () + H (); }