1 // This testcase was miscompiled on IA-64 to read from unitialized memory
2 // and dereference it.
3 // { dg-do run }
4 // { dg-options "-O2" }
5 
6 struct A
7 {
AA8   A () { a = 1; }
a1A9   void a1 () { a++; }
a2A10   bool a2 () { return !--a; }
11   unsigned int a;
12 };
13 
14 struct B {};
15 
16 template <class T> struct C
17 {
CC18   C () {}
CC19   C (const T& t) : c (t) {}
20   C<T> *next, *prev;
21   T c;
22 };
23 
24 template <class T> struct D
25 {
26   C<T> *d;
DD27   D () : d (0) {}
DD28   D (C<T> *x) : d (x) {}
DD29   D (const D<T>& x) : d (x.d) {}
30   bool operator!= (const D<T>& x) const { return d != x.d; }
31   const T& operator* () const { return d->c; }
32   D<T> operator++ (int) { D<T> t = *this; d = d->next; return t; }
33 };
34 
35 template <class T> struct E
36 {
37   C<T> *e;
EE38   E () : e (0) {}
EE39   E (C<T> *p) : e (p) {}
EE40   E (const E<T>& x) : e (x.e) {}
EE41   E (const D<T>& x) : e (x.e) {}
42   bool operator!= (const E<T>& x) const { return e != x.e; }
43   const T& operator* () const { return e->c; }
44   E<T>& operator++ () { e = e->next; return *this; }
45 };
46 
47 template <class T> struct F : public A
48 {
49   C<T> *f;
50   unsigned long f0;
FF51   F () { f = new C<T>; f->next = f->prev = f; f0 = 0; }
FF52   F (const F<T>& x) : A ()
53   {
54     f = new C<T>; f->next = f->prev = f; f0 = 0;
55     D<T> b (x.f->next), e (x.f), i (f);
56     while (b != e)
57       f1 (i, *b++);
58   }
59 
~FF60   ~F ()
61   {
62     C<T> *p = f->next;
63     while (p != f)
64       {
65 	C<T> *x = p->next;
66 	delete p;
67 	p = x;
68       }
69     delete f;
70   }
71 
f1F72   D<T> f1 (D<T> x, const T& y)
73   {
74     C<T> *p = new C<T> (y);
75     p->next = x.d;
76     p->prev = x.d->prev;
77     x.d->prev->next = p;
78     x.d->prev = p;
79     f0++;
80     return p;
81   }
82 };
83 
84 template <class T> struct G
85 {
86   F<T> *g;
GG87   G () { g = new F<T>; }
GG88   G (const G<T>& x) { g = x.g; g->a1 (); }
~GG89   ~G () {}
90   G<T>& operator= (const G<T>& x) { x.g->a1 (); g = x.g; return *this; }
g1G91   D<T> g1 () { g4 (); return D<T> (g->f); }
g1G92   E<T> g1 () const { return E<T> (g->f); }
g2G93   E<T> g2 () const { return E<T> (g->f->next); }
g3G94   D<T> g3 (const T& x) { g4 (); return g->f1 (g1 (), x); }
g4G95   void g4 () { if (g->a > 1) { g->a2 (); g = new F<T> (*g); } }
96 
97   G<T> operator+ (const G<T>& x) const
98   {
99     G<T> x2 (*this);
100     for (E<T> i = x.g2 (); i != x.g1 (); ++i)
101       x2.g3 (*i);
102     return x2;
103   }
104 
105   G<T>& operator+= (const G<T>& x)
106   {
107     for (E<T> i = x.g2 (); i != x.g1 (); ++i)
108       g3 (*i);
109     return *this;
110   }
111 };
112 
113 struct H : public G<B>
114 {
HH115   H () {}
HH116   H (const H& x) : G<B> (x) {}
HH117   H (const G<B>& x) : G<B> (x) {}
118 };
119 
120 void foo ();
121 
122 int
main()123 main ()
124 {
125   H a = H () + H ();
126   a += H ();
127   H b;
128   b = H () + H ();
129 }
130