OSDN Git Service

PR middle-end/6247
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Apr 2002 21:49:26 +0000 (21:49 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Apr 2002 21:49:26 +0000 (21:49 +0000)
* g++.dg/opt/cleanup1.C: New test.

* g++.dg/opt/const1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52146 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/cleanup1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/const1.C [new file with mode: 0644]

index a7148b9..001802f 100644 (file)
@@ -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>
  
        * gcc.c-torture/execute/20020406-1.c: Declare malloc.
diff --git a/gcc/testsuite/g++.dg/opt/cleanup1.C b/gcc/testsuite/g++.dg/opt/cleanup1.C
new file mode 100644 (file)
index 0000000..f34c7cf
--- /dev/null
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/opt/const1.C b/gcc/testsuite/g++.dg/opt/const1.C
new file mode 100644 (file)
index 0000000..834cfd5
--- /dev/null
@@ -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 ();
+}