blob: d37e6109db4aec3f9194c9aecfa80e4aeacb0321 [file] [log] [blame]
Anders Carlsson6774b1f2011-02-28 00:40:07 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
Anders Carlssonafd1edb2009-12-11 00:32:37 +00002
John McCall824c2f52010-09-14 07:57:04 +00003typedef typeof(sizeof(0)) size_t;
Anders Carlssonafd1edb2009-12-11 00:32:37 +00004
John McCall824c2f52010-09-14 07:57:04 +00005// This just shouldn't crash.
6namespace test0 {
7 struct allocator {
8 allocator();
9 allocator(const allocator&);
10 ~allocator();
11 };
Anders Carlssonafd1edb2009-12-11 00:32:37 +000012
John McCall824c2f52010-09-14 07:57:04 +000013 void f();
14 void g(bool b, bool c) {
15 if (b) {
16 if (!c)
17 throw allocator();
18
19 return;
20 }
21 f();
Anders Carlssonafd1edb2009-12-11 00:32:37 +000022 }
John McCall824c2f52010-09-14 07:57:04 +000023}
24
25namespace test1 {
26 struct A { A(int); A(int, int); ~A(); void *p; };
27
28 A *a() {
29 // CHECK: define [[A:%.*]]* @_ZN5test11aEv()
30 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
31 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
32 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5)
33 // CHECK: ret [[A]]* [[CAST]]
34 // CHECK: call void @_ZdlPv(i8* [[NEW]])
35 return new A(5);
36 }
37
38 A *b() {
39 // CHECK: define [[A:%.*]]* @_ZN5test11bEv()
40 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
41 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
42 // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
43 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]])
44 // CHECK: ret [[A]]* [[CAST]]
45 // CHECK: call void @_ZdlPv(i8* [[NEW]])
46 extern int foo();
47 return new A(foo());
48 }
49
50 struct B { B(); ~B(); operator int(); int x; };
51 B makeB();
52
53 A *c() {
54 // CHECK: define [[A:%.*]]* @_ZN5test11cEv()
55 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCall824c2f52010-09-14 07:57:04 +000056 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCallf4beacd2011-11-10 10:43:54 +000057 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +000058 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
59 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
60 // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0
61 // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4
62 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]])
63 // CHECK: store i1 false, i1* [[ACTIVE]]
64 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
65 // CHECK: ret [[A]]* [[CAST]]
66 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
67 // CHECK-NEXT: br i1 [[ISACTIVE]]
68 // CHECK: call void @_ZdlPv(i8* [[NEW]])
69 return new A(B().x);
70 }
71
John McCalle142ad52013-02-12 03:51:46 +000072 // rdar://11904428
73 // Terminate landing pads should call __cxa_begin_catch first.
Bill Wendling2386bb12013-02-27 00:06:04 +000074 // CHECK: define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]]
Bill Wendlinge1c4a1b2013-02-22 09:10:20 +000075 // CHECK-NEXT: [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]]
76 // CHECK-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
John McCalle142ad52013-02-12 03:51:46 +000077 // CHECK-NEXT: unreachable
78
John McCall824c2f52010-09-14 07:57:04 +000079 A *d() {
80 // CHECK: define [[A:%.*]]* @_ZN5test11dEv()
81 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCall824c2f52010-09-14 07:57:04 +000082 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCallf4beacd2011-11-10 10:43:54 +000083 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +000084 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
85 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
86 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
87 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
88 // CHECK: store i1 false, i1* [[ACTIVE]]
89 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
90 // CHECK: ret [[A]]* [[CAST]]
91 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
92 // CHECK-NEXT: br i1 [[ISACTIVE]]
93 // CHECK: call void @_ZdlPv(i8* [[NEW]])
94 return new A(B());
95 }
96
97 A *e() {
98 // CHECK: define [[A:%.*]]* @_ZN5test11eEv()
99 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCall824c2f52010-09-14 07:57:04 +0000100 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCallf4beacd2011-11-10 10:43:54 +0000101 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +0000102 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
103 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
104 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
105 // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]])
106 // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
107 // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
108 // CHECK: store i1 false, i1* [[ACTIVE]]
109 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
110 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
111 // CHECK: ret [[A]]* [[CAST]]
112 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
113 // CHECK-NEXT: br i1 [[ISACTIVE]]
114 // CHECK: call void @_ZdlPv(i8* [[NEW]])
115 return new A(B(), B());
116 }
117 A *f() {
118 return new A(makeB().x);
119 }
120 A *g() {
121 return new A(makeB());
122 }
123 A *h() {
124 return new A(makeB(), makeB());
125 }
126
127 A *i() {
128 // CHECK: define [[A:%.*]]* @_ZN5test11iEv()
129 // CHECK: [[X:%.*]] = alloca [[A]]*, align 8
130 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCallf4beacd2011-11-10 10:43:54 +0000131 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
132 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +0000133 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
134 // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
135 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
136 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
137 // CHECK: store i1 false, i1* [[ACTIVE]]
138 // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
139 // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
140 // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8
141 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
142 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
143 // CHECK: ret [[A]]* [[RET]]
144 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
145 // CHECK-NEXT: br i1 [[ISACTIVE]]
146 // CHECK: call void @_ZdlPv(i8* [[NEW]])
147 A *x;
148 return (x = new A(makeB()), makeB(), x);
149 }
150}
151
152namespace test2 {
153 struct A {
154 A(int); A(int, int); ~A();
155 void *p;
156 void *operator new(size_t);
157 void operator delete(void*, size_t);
158 };
159
160 A *a() {
161 // CHECK: define [[A:%.*]]* @_ZN5test21aEv()
162 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8)
163 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
164 // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
165 // CHECK: ret [[A]]* [[CAST]]
166 // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
Bill Wendlinge1c4a1b2013-02-22 09:10:20 +0000167 // CHECK: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
John McCall824c2f52010-09-14 07:57:04 +0000168 return new A(5);
169 }
170}
171
172namespace test3 {
173 struct A {
John McCall7f9c92a2010-09-17 00:50:28 +0000174 A(int); A(int, int); A(const A&); ~A();
John McCall824c2f52010-09-14 07:57:04 +0000175 void *p;
John McCall7f9c92a2010-09-17 00:50:28 +0000176 void *operator new(size_t, void*, double);
177 void operator delete(void*, void*, double);
John McCall824c2f52010-09-14 07:57:04 +0000178 };
179
John McCall7f9c92a2010-09-17 00:50:28 +0000180 void *foo();
181 double bar();
182 A makeA(), *makeAPtr();
183
John McCall824c2f52010-09-14 07:57:04 +0000184 A *a() {
185 // CHECK: define [[A:%.*]]* @_ZN5test31aEv()
186 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
John McCall7f9c92a2010-09-17 00:50:28 +0000187 // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
188 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
John McCall824c2f52010-09-14 07:57:04 +0000189 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
190 // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
191 // CHECK: ret [[A]]* [[CAST]]
John McCall7f9c92a2010-09-17 00:50:28 +0000192 // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
Bill Wendlinge1c4a1b2013-02-22 09:10:20 +0000193 // CHECK: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]]
John McCall824c2f52010-09-14 07:57:04 +0000194 return new(foo(),bar()) A(5);
195 }
John McCall7f9c92a2010-09-17 00:50:28 +0000196
197 // rdar://problem/8439196
198 A *b(bool cond) {
199
200 // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
201 // CHECK: [[SAVED0:%.*]] = alloca i8*
202 // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
203 // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
John McCall7f9c92a2010-09-17 00:50:28 +0000204
205 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
John McCallf4beacd2011-11-10 10:43:54 +0000206 // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
John McCall7f9c92a2010-09-17 00:50:28 +0000207 // CHECK-NEXT: br i1 [[COND]]
208 return (cond ?
209
210 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
211 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
212 // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
213 // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
214 // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
215 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
Eli Friedmanb971d492012-02-16 22:45:48 +0000216 // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]])
217 // CHECK: br label
John McCall7f9c92a2010-09-17 00:50:28 +0000218 // -> cond.end
219 new(foo(),10.0) A(makeA()) :
220
Eli Friedmanb971d492012-02-16 22:45:48 +0000221 // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
John McCall7f9c92a2010-09-17 00:50:28 +0000222 // CHECK: br label
223 // -> cond.end
224 makeAPtr());
225
226 // cond.end:
227 // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
John McCall7f9c92a2010-09-17 00:50:28 +0000228 // CHECK: ret [[A]]* [[RESULT]]
229
230 // in the EH path:
231 // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]]
232 // CHECK-NEXT: br i1 [[ISACTIVE]]
233 // CHECK: [[V0:%.*]] = load i8** [[SAVED0]]
234 // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]]
235 // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
236 }
John McCall824c2f52010-09-14 07:57:04 +0000237}
238
239namespace test4 {
240 struct A {
241 A(int); A(int, int); ~A();
242 void *p;
243 void *operator new(size_t, void*, void*);
244 void operator delete(void*, size_t, void*, void*); // not a match
245 };
246
247 A *a() {
248 // CHECK: define [[A:%.*]]* @_ZN5test41aEv()
249 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv()
250 // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv()
251 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
252 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
253 // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5)
254 // CHECK-NEXT: ret [[A]]* [[CAST]]
255 extern void *foo(), *bar();
256
257 return new(foo(),bar()) A(5);
258 }
Anders Carlssonafd1edb2009-12-11 00:32:37 +0000259}
John McCall1bf58462011-02-16 08:02:54 +0000260
261// PR7908
262namespace test5 {
263 struct T { T(); ~T(); };
264
265 struct A {
266 A(const A &x, const T &t = T());
267 ~A();
268 };
269
270 void foo();
271
Stephen Lin43622612013-08-15 06:47:53 +0000272 // CHECK-LABEL: define void @_ZN5test54testEv()
John McCall1bf58462011-02-16 08:02:54 +0000273 // CHECK: [[EXNSLOT:%.*]] = alloca i8*
John McCall9b382dd2011-05-28 21:13:02 +0000274 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
John McCall1bf58462011-02-16 08:02:54 +0000275 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
276 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
John McCall1bf58462011-02-16 08:02:54 +0000277 // CHECK-NEXT: invoke void @_ZN5test53fooEv()
278 // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]]
279 // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
280 // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
281 // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
282 // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
283 // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
Bill Wendlinge1c4a1b2013-02-22 09:10:20 +0000284 // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]]
John McCall1bf58462011-02-16 08:02:54 +0000285 // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
286 // CHECK: call void @__cxa_end_catch()
287 void test() {
288 try {
289 foo();
290 } catch (A a) {
291 }
292 }
293}
John McCall1b93f1b2011-02-25 04:19:13 +0000294
295// PR9303: invalid assert on this
296namespace test6 {
297 bool cond();
298 void test() {
299 try {
300 lbl:
301 if (cond()) goto lbl;
302 } catch (...) {
303 }
304 }
305}
John McCallf7dcf322011-03-07 01:52:56 +0000306
307// PR9298
308namespace test7 {
309 struct A { A(); ~A(); };
310 struct B {
311 // The throw() operator means that a bad allocation is signalled
312 // with a null return, which means that the initializer is
313 // evaluated conditionally.
314 static void *operator new(size_t size) throw();
315 B(const A&, B*);
316 ~B();
317 };
318
John McCallf7dcf322011-03-07 01:52:56 +0000319 B *test() {
John McCall75f94982011-03-07 03:12:35 +0000320 // CHECK: define [[B:%.*]]* @_ZN5test74testEv()
321 // CHECK: [[OUTER_NEW:%.*]] = alloca i1
322 // CHECK-NEXT: alloca [[A:%.*]],
323 // CHECK-NEXT: alloca i8*
324 // CHECK-NEXT: alloca i32
325 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
326 // CHECK-NEXT: alloca i8*
327 // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
328 // CHECK-NEXT: alloca [[A]]
329 // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
330
John McCall75f94982011-03-07 03:12:35 +0000331 // Allocate the outer object.
332 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
333 // CHECK-NEXT: icmp eq i8* [[NEW]], null
334
335 // These stores, emitted before the outermost conditional branch,
336 // deactivate the temporary cleanups.
John McCallf4beacd2011-11-10 10:43:54 +0000337 // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]]
John McCall75f94982011-03-07 03:12:35 +0000338 // CHECK-NEXT: store i1 false, i1* [[OUTER_A]]
John McCallf4beacd2011-11-10 10:43:54 +0000339 // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]]
John McCall75f94982011-03-07 03:12:35 +0000340 // CHECK-NEXT: store i1 false, i1* [[INNER_A]]
341 // CHECK-NEXT: br i1
342
343 // We passed the first null check; activate that cleanup and continue.
344 // CHECK: store i1 true, i1* [[OUTER_NEW]]
345 // CHECK-NEXT: bitcast
346
347 // Create the first A temporary and activate that cleanup.
348 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
349 // CHECK: store i1 true, i1* [[OUTER_A]]
350
351 // Allocate the inner object.
352 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
353 // CHECK-NEXT: icmp eq i8* [[NEW]], null
354 // CHECK-NEXT: br i1
355
356 // We passed the second null check; save that pointer, activate
357 // that cleanup, and continue.
358 // CHECK: store i8* [[NEW]]
359 // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]]
360 // CHECK-NEXT: bitcast
361
362 // Build the second A temporary and activate that cleanup.
363 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
364 // CHECK: store i1 true, i1* [[INNER_A]]
365
366 // Build the inner B object and deactivate the inner delete cleanup.
367 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
368 // CHECK: store i1 false, i1* [[INNER_NEW]]
369 // CHECK: phi
370
371 // Build the outer B object and deactivate the outer delete cleanup.
372 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
373 // CHECK: store i1 false, i1* [[OUTER_NEW]]
374 // CHECK: phi
John McCallb0433ee2012-09-25 06:56:03 +0000375 // CHECK-NEXT: store [[B]]*
John McCall75f94982011-03-07 03:12:35 +0000376
377 // Destroy the inner A object.
378 // CHECK-NEXT: load i1* [[INNER_A]]
379 // CHECK-NEXT: br i1
380 // CHECK: invoke void @_ZN5test71AD1Ev(
381
382 // Destroy the outer A object.
383 // CHECK: load i1* [[OUTER_A]]
384 // CHECK-NEXT: br i1
385 // CHECK: invoke void @_ZN5test71AD1Ev(
386
John McCallf7dcf322011-03-07 01:52:56 +0000387 return new B(A(), new B(A(), 0));
388 }
389}
John McCall35e4f0c2011-08-26 00:46:38 +0000390
391// Just don't crash.
392namespace test8 {
393 struct A {
John McCalla8a39bc2011-08-26 05:38:08 +0000394 // Having both of these is required to trigger the assert we're
395 // trying to avoid.
John McCall35e4f0c2011-08-26 00:46:38 +0000396 A(const A&);
John McCalla8a39bc2011-08-26 05:38:08 +0000397 A&operator=(const A&);
398
John McCall35e4f0c2011-08-26 00:46:38 +0000399 ~A();
400 };
401
402 A makeA();
403 void test() {
404 throw makeA();
405 }
Stephen Lin43622612013-08-15 06:47:53 +0000406 // CHECK-LABEL: define void @_ZN5test84testEv
Eli Friedmancf9b1f62011-09-06 18:53:03 +0000407}
408
409// Make sure we generate the correct code for the delete[] call which
410// happens if A::A() throws. (We were previously calling delete[] on
411// a pointer to the first array element, not the pointer returned by new[].)
412// PR10870
413namespace test9 {
414 struct A {
415 A();
416 ~A();
417 };
418 A* test() {
419 return new A[10];
420 }
421 // CHECK: define {{%.*}}* @_ZN5test94testEv
422 // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam
423 // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
John McCall35e4f0c2011-08-26 00:46:38 +0000424}
John McCalld8d00be2012-06-15 05:27:05 +0000425
426// In a destructor with a function-try-block, a return statement in a
427// catch handler behaves differently from running off the end of the
428// catch handler. PR13102.
429namespace test10 {
430 extern void cleanup();
431 extern bool suppress;
432
433 struct A { ~A(); };
434 A::~A() try { cleanup(); } catch (...) { return; }
Stephen Lin43622612013-08-15 06:47:53 +0000435 // CHECK-LABEL: define void @_ZN6test101AD1Ev(
John McCalld8d00be2012-06-15 05:27:05 +0000436 // CHECK: invoke void @_ZN6test107cleanupEv()
437 // CHECK-NOT: rethrow
438 // CHECK: ret void
439
440 struct B { ~B(); };
441 B::~B() try { cleanup(); } catch (...) {}
Stephen Lin43622612013-08-15 06:47:53 +0000442 // CHECK-LABEL: define void @_ZN6test101BD1Ev(
John McCalld8d00be2012-06-15 05:27:05 +0000443 // CHECK: invoke void @_ZN6test107cleanupEv()
444 // CHECK: call i8* @__cxa_begin_catch
445 // CHECK-NEXT: invoke void @__cxa_rethrow()
446 // CHECK: unreachable
447
448 struct C { ~C(); };
449 C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
Stephen Lin43622612013-08-15 06:47:53 +0000450 // CHECK-LABEL: define void @_ZN6test101CD1Ev(
John McCalld8d00be2012-06-15 05:27:05 +0000451 // CHECK: invoke void @_ZN6test107cleanupEv()
452 // CHECK: call i8* @__cxa_begin_catch
453 // CHECK-NEXT: load i8* @_ZN6test108suppressE, align 1
454 // CHECK-NEXT: trunc
455 // CHECK-NEXT: br i1
456 // CHECK: call void @__cxa_end_catch()
457 // CHECK-NEXT: br label
458 // CHECK: invoke void @__cxa_rethrow()
459 // CHECK: unreachable
460}
John McCall12cc42a2013-02-01 05:11:40 +0000461
462// Ensure that an exception in a constructor destroys
463// already-constructed array members. PR14514
464namespace test11 {
465 struct A {
466 A();
467 ~A() {}
468 };
469
470 struct C {
471 A single;
472 A array[2][3];
473
474 C();
475 };
476
477 C::C() {
478 throw 0;
479 }
Stephen Lin43622612013-08-15 06:47:53 +0000480 // CHECK-LABEL: define void @_ZN6test111CC2Ev(
John McCall12cc42a2013-02-01 05:11:40 +0000481 // CHECK: [[THIS:%.*]] = load [[C:%.*]]** {{%.*}}
482 // Construct single.
483 // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 0
484 // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]])
485 // Construct array.
486 // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 1
487 // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
488 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6
489 // CHECK-NEXT: br label
490 // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
491 // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]])
492 // CHECK: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
493 // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]]
494 // CHECK-NEXT: br i1 [[DONE]],
495 // throw 0;
496 // CHECK: invoke void @__cxa_throw(
497 // Landing pad 1, from constructor in array-initialization loop:
498 // CHECK: landingpad
499 // - First, destroy already-constructed bits of array.
500 // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]]
501 // CHECK-NEXT: br i1 [[EMPTY]]
502 // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
503 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
504 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
505 // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
506 // CHECK-NEXT: br i1 [[DONE]],
507 // - Next, chain to cleanup for single.
508 // CHECK: br label
509 // Landing pad 2, from throw site.
510 // CHECK: landingpad
511 // - First, destroy all of array.
512 // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
513 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6
514 // CHECK-NEXT: br label
515 // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
516 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
517 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
518 // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
519 // CHECK-NEXT: br i1 [[DONE]],
520 // - Next, chain to cleanup for single.
521 // CHECK: br label
522 // Finally, the cleanup for single.
523 // CHECK: invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
524 // CHECK: br label
525 // CHECK: resume
526 // (After this is a terminate landingpad.)
527}
Bill Wendlingc33fc4c2013-02-20 07:22:19 +0000528
Bill Wendling2386bb12013-02-27 00:06:04 +0000529// CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }