aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
committerBen Cheng <bccheng@google.com>2014-03-25 22:37:19 -0700
commit1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch)
treec607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C
parent283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff)
downloadtoolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2
toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C')
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C255
1 files changed, 255 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C b/gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C
new file mode 100644
index 000000000..0c31f80e5
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/eh/async-unwind2.C
@@ -0,0 +1,255 @@
+// PR rtl-optimization/36419
+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+// { dg-require-effective-target fpic }
+// { dg-options "-Os -fasynchronous-unwind-tables -fpic -fno-inline" }
+
+#include <stdarg.h>
+
+extern "C" void abort ();
+
+extern "C"
+{
+ struct R { int r1; unsigned short r2[1]; };
+ int bar1 (unsigned short *, int, short) throw ();
+ void bar2 (R *) throw ();
+ void bar3 (R **, const unsigned short *, int) throw ();
+ void bar4 (R **, const char *) throw ();
+ void bar5 (void *, const char *, ...);
+}
+
+struct S
+{
+ R *s;
+ struct T { };
+ S (R *x, T *) { s = x; }
+ ~S () { bar2 (s); }
+ S &operator= (const S &x);
+ S &operator+= (const S &x);
+ S sfn1 (const S &x) const;
+ friend S operator+ (const S &x1, const S &x2);
+ static S sfn2 (int i)
+ {
+ unsigned short q[33];
+ R *p = 0;
+ bar3 (&p, q, bar1 (q, i, 10));
+ return S (p, (T *) 0);
+ }
+ static S sfn3 (const char *x)
+ {
+ R *p = 0;
+ bar4 (&p, x);
+ return S (p, (T *) 0);
+ }
+};
+
+struct U { };
+template <class C> unsigned char operator >>= (const U &, C &);
+
+struct V;
+struct W
+{
+ V *w;
+ unsigned char is () const;
+};
+
+template <class T> struct X : public W
+{
+ inline ~X ();
+ X ();
+ X (const W &);
+ T *operator -> () const;
+};
+
+struct E
+{
+ E ();
+ E (const S &, const X <V> &);
+ E (E const &);
+ ~E ();
+ E &operator = (E const &);
+};
+
+struct V
+{
+ virtual void release () throw ();
+};
+
+template <class T> X <T>::~X ()
+{
+ if (w)
+ w->release ();
+}
+
+struct Y
+{
+ virtual U yfn1 (const S &);
+};
+
+struct Z;
+
+X <V> baz1 (const S &) throw (E);
+X <Z> baz2 (const X <Z> &) throw (E);
+
+template <typename T> X<T>::X ()
+{
+ w = __null;
+}
+
+template <typename T> X<T>::X (W const &)
+{
+ w = __null;
+}
+
+U Y::yfn1 (const S &)
+{
+ throw 12;
+}
+
+Y y;
+
+template <typename T> T *X<T>::operator -> () const
+{
+ return &y;
+}
+
+X <V> baz1 (const S &) throw (E)
+{
+ return X<V> ();
+}
+
+E::E ()
+{
+}
+
+E::~E ()
+{
+}
+
+X <Z> baz2 (const X <Z> &) throw (E)
+{
+ throw E ();
+}
+
+int bar1 (unsigned short *, int, short) throw ()
+{
+ asm volatile ("" : : : "memory");
+ return 0;
+}
+
+void bar2 (R *) throw ()
+{
+ asm volatile ("" : : : "memory");
+}
+
+void bar3 (R **, const unsigned short *, int) throw ()
+{
+ asm volatile ("" : : : "memory");
+}
+
+void bar4 (R **, const char *) throw ()
+{
+ asm volatile ("" : : : "memory");
+}
+
+int events[2];
+void *sp;
+
+void bar5 (void *p, const char *s, ...)
+{
+ va_list ap;
+ va_start (ap, s);
+ if (p)
+ throw 19;
+ switch (*s)
+ {
+ case 't':
+ if (events[0] != va_arg (ap, int))
+ abort ();
+ events[0]++;
+ break;
+ case 'f':
+ abort ();
+ case 'c':
+ if (events[1] != va_arg (ap, int))
+ abort ();
+ events[1]++;
+ if (events[1] == 1)
+ sp = va_arg (ap, void *);
+ else if (sp != va_arg (ap, void *))
+ abort ();
+ break;
+ }
+}
+
+unsigned char W::is () const
+{
+ return 1;
+}
+
+S &S::operator += (const S &)
+{
+ return *this;
+}
+
+template <class C> unsigned char operator >>= (const U &, C &)
+{
+ throw 1;
+}
+
+template X<Y>::X ();
+template X<Z>::X ();
+template unsigned char operator >>= (const U &, X<Z> &);
+template X<Y>::X (W const &);
+
+template Y *X<Y>::operator-> () const;
+
+X <Z> foo () throw ()
+{
+ X <Z> a;
+ X <Y> b;
+ try
+ {
+ b = X <Y> (baz1 (S::sfn3 ("defg")));
+ }
+ catch (E &)
+ {
+ }
+ if (b.is ())
+ {
+ for (int n = 0; n < 10; n++)
+ {
+ S c = S::sfn3 ("abcd");
+ c += S::sfn2 (n);
+ X <Z> d;
+ try
+ {
+ bar5 ((void *) 0, "trying %d\n", n);
+ if ((b->yfn1 (c) >>= d))
+ if (d.is ())
+ {
+ bar5 ((void *) 0, "failure1 on %d\n", n);
+ a = baz2 (d);
+ if (a.is ())
+ break;
+ }
+ bar5 ((void *) 0, "failure2 on %d\n", n);
+ }
+ catch (...)
+ {
+ void *p;
+ asm volatile ("movl %%esp, %0" : "=r" (p));
+ bar5 ((void *) 0, "caught %d %p\n", n, p);
+ }
+ }
+ }
+ return a;
+}
+
+int
+main ()
+{
+ foo ();
+ if (events[0] != 10 || events[1] != 10)
+ abort ();
+ return 0;
+}