re PR middle-end/6247 (Konqueror miscompilation on IA-32)
PR middle-end/6247 * g++.dg/opt/cleanup1.C: New test. * g++.dg/opt/const1.C: New test. From-SVN: r52146
This commit is contained in:
parent
880f8c16ad
commit
dab550cb99
|
@ -1,3 +1,10 @@
|
||||||
|
2002-04-10 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR middle-end/6247
|
||||||
|
* g++.dg/opt/cleanup1.C: New test.
|
||||||
|
|
||||||
|
* g++.dg/opt/const1.C: New test.
|
||||||
|
|
||||||
2002-04-10 Lars Brinkhoff <lars@nocrew.org>
|
2002-04-10 Lars Brinkhoff <lars@nocrew.org>
|
||||||
|
|
||||||
* gcc.c-torture/execute/20020406-1.c: Declare malloc.
|
* gcc.c-torture/execute/20020406-1.c: Declare malloc.
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
// 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.
|
||||||
|
// { 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 <class T> struct D
|
||||||
|
{
|
||||||
|
D (const T& t) : d (t) {}
|
||||||
|
D () {}
|
||||||
|
D<T> *next, *prev;
|
||||||
|
T d;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct E
|
||||||
|
{
|
||||||
|
D<T> *e;
|
||||||
|
E () : e (0) {}
|
||||||
|
E (D<T> *p) : e (p) {}
|
||||||
|
E (const E<T>& x) : e (x.e) {}
|
||||||
|
const T& operator* () const { return e->d; }
|
||||||
|
T& operator* () { return e->d; }
|
||||||
|
bool operator== (const E<T>& x) const { return e == x.e; }
|
||||||
|
bool operator!= (const E<T>& x) const { return e != x.e; }
|
||||||
|
E<T> operator++ (int) { E<T> x = *this; e = e->next; return x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> struct F : public A
|
||||||
|
{
|
||||||
|
F () { f = new D<T>; f->next = f->prev = f; f0 = 0; }
|
||||||
|
~F () {}
|
||||||
|
D<T> *f;
|
||||||
|
unsigned int f0;
|
||||||
|
|
||||||
|
F (const F<T>& x) : A ()
|
||||||
|
{
|
||||||
|
f = new D<T>; f->next = f->prev = f; f0 = 0;
|
||||||
|
E<T> b (x.f->next);
|
||||||
|
E<T> e (x.f);
|
||||||
|
E<T> i (f);
|
||||||
|
while (b != e)
|
||||||
|
f1 (i, *b++);
|
||||||
|
}
|
||||||
|
|
||||||
|
E<T> f1 (E<T> x, const T& y)
|
||||||
|
{
|
||||||
|
D<T> *p = new D<T> (y);
|
||||||
|
p->next = x.e;
|
||||||
|
p->prev = x.e->prev;
|
||||||
|
x.e->prev->next = p;
|
||||||
|
x.e->prev = p;
|
||||||
|
f0++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> struct G
|
||||||
|
{
|
||||||
|
E<T> g1 () { g3 (); return E<T> (g->f); }
|
||||||
|
E<T> g2 (const T& x) { g3 (); return g->f1 (g1 (), x); }
|
||||||
|
void g3 () { if (g->a > 1) { g->a2 (); g = new F<T> (*g); } }
|
||||||
|
F<T>* g;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct H
|
||||||
|
{
|
||||||
|
virtual ~H () {};
|
||||||
|
virtual void h1 ();
|
||||||
|
struct I
|
||||||
|
{
|
||||||
|
I () {}
|
||||||
|
I (C r, C p) : i1 (r), i2 (p) {}
|
||||||
|
C i1, i2;
|
||||||
|
};
|
||||||
|
G<I> 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::C (const C &x)
|
||||||
|
{
|
||||||
|
c = x.c;
|
||||||
|
c->a1 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
H h;
|
||||||
|
h.h.g = new F<H::I> ();
|
||||||
|
h.h1 ();
|
||||||
|
if (h.h.g->f0 != 3)
|
||||||
|
abort ();
|
||||||
|
D<H::I> *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);
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
// 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 ();
|
||||||
|
}
|
Loading…
Reference in New Issue