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" }
5
6 #include <stdarg.h>
7
8 extern "C" void abort ();
9
10 extern "C"
11 {
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 *, ...);
18 }
19
20 struct S
21 {
22 R *s;
23 struct T { };
SS24 S (R *x, T *) { s = x; }
~SS25 ~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);
sfn2S30 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 }
sfn3S37 static S sfn3 (const char *x)
38 {
39 R *p = 0;
40 bar4 (&p, x);
41 return S (p, (T *) 0);
42 }
43 };
44
45 struct U { };
46 template <class C> unsigned char operator >>= (const U &, C &);
47
48 struct V;
49 struct W
50 {
51 V *w;
52 unsigned char is () const;
53 };
54
55 template <class T> struct X : public W
56 {
57 inline ~X ();
58 X ();
59 X (const W &);
60 T *operator -> () const;
61 };
62
63 struct E
64 {
65 E ();
66 E (const S &, const X <V> &);
67 E (E const &);
68 ~E ();
69 E &operator = (E const &);
70 };
71
72 struct V
73 {
74 virtual void release () throw ();
75 };
76
~X()77 template <class T> X <T>::~X ()
78 {
79 if (w)
80 w->release ();
81 }
82
83 struct Y
84 {
85 virtual U yfn1 (const S &);
86 };
87
88 struct Z;
89
90 X <V> baz1 (const S &)
91 #if __cplusplus <= 201402L
92 throw (E) // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
93 #endif
94 ;
95 X <Z> baz2 (const X <Z> &)
96 #if __cplusplus <= 201402L
97 throw (E) // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
98 #endif
99 ;
100
X()101 template <typename T> X<T>::X ()
102 {
103 w = __null;
104 }
105
X(W const &)106 template <typename T> X<T>::X (W const &)
107 {
108 w = __null;
109 }
110
yfn1(const S &)111 U Y::yfn1 (const S &)
112 {
113 throw 12;
114 }
115
116 Y y;
117
118 template <typename T> T *X<T>::operator -> () const
119 {
120 return &y;
121 }
122
baz1(const S &)123 X <V> baz1 (const S &)
124 #if __cplusplus <= 201402L
125 throw (E) // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
126 #endif
127 {
128 return X<V> ();
129 }
130
E()131 E::E ()
132 {
133 }
134
~E()135 E::~E ()
136 {
137 }
138
baz2(const X<Z> &)139 X <Z> baz2 (const X <Z> &)
140 #if __cplusplus <= 201402L
141 throw (E) // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
142 #endif
143 {
144 throw E ();
145 }
146
bar1(unsigned short *,int,short)147 int bar1 (unsigned short *, int, short) throw ()
148 {
149 asm volatile ("" : : : "memory");
150 return 0;
151 }
152
bar2(R *)153 void bar2 (R *) throw ()
154 {
155 asm volatile ("" : : : "memory");
156 }
157
bar3(R **,const unsigned short *,int)158 void bar3 (R **, const unsigned short *, int) throw ()
159 {
160 asm volatile ("" : : : "memory");
161 }
162
bar4(R **,const char *)163 void bar4 (R **, const char *) throw ()
164 {
165 asm volatile ("" : : : "memory");
166 }
167
168 int events[2];
169 void *sp;
170
bar5(void * p,const char * s,...)171 void bar5 (void *p, const char *s, ...)
172 {
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 }
196 }
197
is()198 unsigned char W::is () const
199 {
200 return 1;
201 }
202
203 S &S::operator += (const S &)
204 {
205 return *this;
206 }
207
208 template <class C> unsigned char operator >>= (const U &, C &)
209 {
210 throw 1;
211 }
212
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 &);
217
218 template Y *X<Y>::operator-> () const;
219
foo()220 X <Z> foo () throw ()
221 {
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;
260 }
261
262 int
main()263 main ()
264 {
265 foo ();
266 if (events[0] != 10 || events[1] != 10)
267 abort ();
268 return 0;
269 }
270