[PR c++/84702] ICE with default tmpl arg of overload set
[official-gcc.git] / gcc / testsuite / g++.dg / eh / async-unwind2.C
blob70d38712a032fb802620e8e36d25eb26bf8daf56
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 &)
91 #if __cplusplus <= 201402L
92 throw (E)                       // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
93 #endif
95 X <Z> baz2 (const X <Z> &)
96 #if __cplusplus <= 201402L
97 throw (E)                       // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
98 #endif
101 template <typename T> X<T>::X ()
103   w = __null;
106 template <typename T> X<T>::X (W const &)
108   w = __null;
111 U Y::yfn1 (const S &)
113   throw 12;
116 Y y;
118 template <typename T> T *X<T>::operator -> () const
120   return &y;
123 X <V> baz1 (const S &)
124 #if __cplusplus <= 201402L
125 throw (E)                       // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
126 #endif
128   return X<V> ();
131 E::E ()
135 E::~E ()
139 X <Z> baz2 (const X <Z> &)
140 #if __cplusplus <= 201402L
141 throw (E)                       // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
142 #endif
144   throw E ();
147 int bar1 (unsigned short *, int, short) throw ()
149   asm volatile ("" : : : "memory");
150   return 0;
153 void bar2 (R *) throw ()
155   asm volatile ("" : : : "memory");
158 void bar3 (R **, const unsigned short *, int) throw ()
160   asm volatile ("" : : : "memory");
163 void bar4 (R **, const char *) throw ()
165   asm volatile ("" : : : "memory");
168 int events[2];
169 void *sp;
171 void bar5 (void *p, const char *s, ...)
173   va_list ap;
174   va_start (ap, s);
175   if (p)
176     throw 19;
177   switch (*s)
178     {
179     case 't':
180       if (events[0] != va_arg (ap, int))
181         abort ();
182       events[0]++;
183       break;
184     case 'f':
185       abort ();
186     case 'c':
187       if (events[1] != va_arg (ap, int))
188         abort ();
189       events[1]++;
190       if (events[1] == 1)
191         sp = va_arg (ap, void *);
192       else if (sp != va_arg (ap, void *))
193         abort ();
194       break;
195     }
198 unsigned char W::is () const
200   return 1;
203 S &S::operator += (const S &)
205   return *this;
208 template <class C> unsigned char operator >>= (const U &, C &)
210   throw 1;
213 template X<Y>::X ();
214 template X<Z>::X ();
215 template unsigned char operator >>= (const U &, X<Z> &);
216 template X<Y>::X (W const &);
218 template Y *X<Y>::operator-> () const;
220 X <Z> foo () throw ()
222   X <Z> a;
223   X <Y> b;
224   try
225   {
226     b = X <Y> (baz1 (S::sfn3 ("defg")));
227   }
228   catch (E &)
229   {
230   }
231   if (b.is ())
232     {
233       for (int n = 0; n < 10; n++)
234         {
235           S c = S::sfn3 ("abcd");
236           c += S::sfn2 (n);
237           X <Z> d;
238           try
239           {
240             bar5 ((void *) 0, "trying %d\n", n);
241             if ((b->yfn1 (c) >>= d))
242               if (d.is ())
243                 {
244                   bar5 ((void *) 0, "failure1 on %d\n", n);
245                   a = baz2 (d);
246                   if (a.is ())
247                     break;
248                 }
249               bar5 ((void *) 0, "failure2 on %d\n", n);
250           }
251           catch (...)
252           {
253             void *p;
254             asm volatile ("movl %%esp, %0" : "=r" (p));
255             bar5 ((void *) 0, "caught %d %p\n", n, p);
256           }
257         }
258     }
259   return a;
263 main ()
265   foo ();
266   if (events[0] != 10 || events[1] != 10)
267     abort ();
268   return 0;