* g++.dg/eh/new1.C: XFAIL on AIX.
[official-gcc.git] / gcc / testsuite / g++.dg / eh / async-unwind2.C
blob0c31f80e5e7ab6d9d35e0e66dd1000f941c73f78
1 // PR rtl-optimization/36419
2 // { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
3 // { dg-require-effective-target fpic }
4 // { dg-options "-Os -fasynchronous-unwind-tables -fpic -fno-inline" }
6 #include <stdarg.h>
8 extern "C" void abort ();
10 extern "C"
12   struct R { int r1; unsigned short r2[1]; };
13   int bar1 (unsigned short *, int, short) throw ();
14   void bar2 (R *) throw ();
15   void bar3 (R **, const unsigned short *, int) throw ();
16   void bar4 (R **, const char *) throw ();
17   void bar5 (void *, const char *, ...);
20 struct S
22   R *s;
23   struct T { };
24   S (R *x, T *) { s = x; }
25   ~S () { bar2 (s); }
26   S &operator= (const S &x);
27   S &operator+= (const S &x);
28   S sfn1 (const S &x) const;
29   friend S operator+ (const S &x1, const S &x2);
30   static S sfn2 (int i)
31   {
32     unsigned short q[33];
33     R *p = 0;
34     bar3 (&p, q, bar1 (q, i, 10));
35     return S (p, (T *) 0);
36   }
37   static S sfn3 (const char *x)
38   {
39     R *p = 0;
40     bar4 (&p, x);
41     return S (p, (T *) 0);
42   }
45 struct U { };
46 template <class C> unsigned char operator >>= (const U &, C &);
48 struct V;
49 struct W
51   V *w;
52   unsigned char is () const;
55 template <class T> struct X : public W
57   inline ~X ();
58   X ();
59   X (const W &);
60   T *operator -> () const;
63 struct E
65   E ();
66   E (const S &, const X <V> &);
67   E (E const &);
68   ~E ();
69   E &operator = (E const &);
72 struct V
74   virtual void release () throw ();
77 template <class T> X <T>::~X ()
79   if (w)
80     w->release ();
83 struct Y
85   virtual U yfn1 (const S &);
88 struct Z;
90 X <V> baz1 (const S &) throw (E);
91 X <Z> baz2 (const X <Z> &) throw (E);
93 template <typename T> X<T>::X ()
95   w = __null;
98 template <typename T> X<T>::X (W const &)
100   w = __null;
103 U Y::yfn1 (const S &)
105   throw 12;
108 Y y;
110 template <typename T> T *X<T>::operator -> () const
112   return &y;
115 X <V> baz1 (const S &) throw (E)
117   return X<V> ();
120 E::E ()
124 E::~E ()
128 X <Z> baz2 (const X <Z> &) throw (E)
130   throw E ();
133 int bar1 (unsigned short *, int, short) throw ()
135   asm volatile ("" : : : "memory");
136   return 0;
139 void bar2 (R *) throw ()
141   asm volatile ("" : : : "memory");
144 void bar3 (R **, const unsigned short *, int) throw ()
146   asm volatile ("" : : : "memory");
149 void bar4 (R **, const char *) throw ()
151   asm volatile ("" : : : "memory");
154 int events[2];
155 void *sp;
157 void bar5 (void *p, const char *s, ...)
159   va_list ap;
160   va_start (ap, s);
161   if (p)
162     throw 19;
163   switch (*s)
164     {
165     case 't':
166       if (events[0] != va_arg (ap, int))
167         abort ();
168       events[0]++;
169       break;
170     case 'f':
171       abort ();
172     case 'c':
173       if (events[1] != va_arg (ap, int))
174         abort ();
175       events[1]++;
176       if (events[1] == 1)
177         sp = va_arg (ap, void *);
178       else if (sp != va_arg (ap, void *))
179         abort ();
180       break;
181     }
184 unsigned char W::is () const
186   return 1;
189 S &S::operator += (const S &)
191   return *this;
194 template <class C> unsigned char operator >>= (const U &, C &)
196   throw 1;
199 template X<Y>::X ();
200 template X<Z>::X ();
201 template unsigned char operator >>= (const U &, X<Z> &);
202 template X<Y>::X (W const &);
204 template Y *X<Y>::operator-> () const;
206 X <Z> foo () throw ()
208   X <Z> a;
209   X <Y> b;
210   try
211   {
212     b = X <Y> (baz1 (S::sfn3 ("defg")));
213   }
214   catch (E &)
215   {
216   }
217   if (b.is ())
218     {
219       for (int n = 0; n < 10; n++)
220         {
221           S c = S::sfn3 ("abcd");
222           c += S::sfn2 (n);
223           X <Z> d;
224           try
225           {
226             bar5 ((void *) 0, "trying %d\n", n);
227             if ((b->yfn1 (c) >>= d))
228               if (d.is ())
229                 {
230                   bar5 ((void *) 0, "failure1 on %d\n", n);
231                   a = baz2 (d);
232                   if (a.is ())
233                     break;
234                 }
235               bar5 ((void *) 0, "failure2 on %d\n", n);
236           }
237           catch (...)
238           {
239             void *p;
240             asm volatile ("movl %%esp, %0" : "=r" (p));
241             bar5 ((void *) 0, "caught %d %p\n", n, p);
242           }
243         }
244     }
245   return a;
249 main ()
251   foo ();
252   if (events[0] != 10 || events[1] != 10)
253     abort ();
254   return 0;