blob: 834cfd5e258ca8b7b9ae9d9fe3cca71fffbb8170 [file] [log] [blame]
// 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 <class T> struct C
{
C () {}
C (const T& t) : c (t) {}
C<T> *next, *prev;
T c;
};
template <class T> struct D
{
C<T> *d;
D () : d (0) {}
D (C<T> *x) : d (x) {}
D (const D<T>& x) : d (x.d) {}
bool operator!= (const D<T>& x) const { return d != x.d; }
const T& operator* () const { return d->c; }
D<T> operator++ (int) { D<T> t = *this; d = d->next; return t; }
};
template <class T> struct E
{
C<T> *e;
E () : e (0) {}
E (C<T> *p) : e (p) {}
E (const E<T>& x) : e (x.e) {}
E (const D<T>& x) : e (x.e) {}
bool operator!= (const E<T>& x) const { return e != x.e; }
const T& operator* () const { return e->c; }
E<T>& operator++ () { e = e->next; return *this; }
};
template <class T> struct F : public A
{
C<T> *f;
unsigned long f0;
F () { f = new C<T>; f->next = f->prev = f; f0 = 0; }
F (const F<T>& x) : A ()
{
f = new C<T>; f->next = f->prev = f; f0 = 0;
D<T> b (x.f->next), e (x.f), i (f);
while (b != e)
f1 (i, *b++);
}
~F ()
{
C<T> *p = f->next;
while (p != f)
{
C<T> *x = p->next;
delete p;
p = x;
}
delete f;
}
D<T> f1 (D<T> x, const T& y)
{
C<T> *p = new C<T> (y);
p->next = x.d;
p->prev = x.d->prev;
x.d->prev->next = p;
x.d->prev = p;
f0++;
return p;
}
};
template <class T> struct G
{
F<T> *g;
G () { g = new F<T>; }
G (const G<T>& x) { g = x.g; g->a1 (); }
~G () {}
G<T>& operator= (const G<T>& x) { x.g->a1 (); g = x.g; return *this; }
D<T> g1 () { g4 (); return D<T> (g->f); }
E<T> g1 () const { return E<T> (g->f); }
E<T> g2 () const { return E<T> (g->f->next); }
D<T> g3 (const T& x) { g4 (); return g->f1 (g1 (), x); }
void g4 () { if (g->a > 1) { g->a2 (); g = new F<T> (*g); } }
G<T> operator+ (const G<T>& x) const
{
G<T> x2 (*this);
for (E<T> i = x.g2 (); i != x.g1 (); ++i)
x2.g3 (*i);
return x2;
}
G<T>& operator+= (const G<T>& x)
{
for (E<T> i = x.g2 (); i != x.g1 (); ++i)
g3 (*i);
return *this;
}
};
struct H : public G<B>
{
H () {}
H (const H& x) : G<B> (x) {}
H (const G<B>& x) : G<B> (x) {}
};
void foo ();
int
main ()
{
H a = H () + H ();
a += H ();
H b;
b = H () + H ();
}