blob: 06003c0cd664ece2d1e22076f80194e010a7590a [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
72 A *d() {
73 // CHECK: define [[A:%.*]]* @_ZN5test11dEv()
74 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCall824c2f52010-09-14 07:57:04 +000075 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCallf4beacd2011-11-10 10:43:54 +000076 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +000077 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
78 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
79 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
80 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
81 // CHECK: store i1 false, i1* [[ACTIVE]]
82 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
83 // CHECK: ret [[A]]* [[CAST]]
84 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
85 // CHECK-NEXT: br i1 [[ISACTIVE]]
86 // CHECK: call void @_ZdlPv(i8* [[NEW]])
87 return new A(B());
88 }
89
90 A *e() {
91 // CHECK: define [[A:%.*]]* @_ZN5test11eEv()
92 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCall824c2f52010-09-14 07:57:04 +000093 // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
John McCallf4beacd2011-11-10 10:43:54 +000094 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +000095 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
96 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]])
97 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
98 // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]])
99 // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]])
100 // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]])
101 // CHECK: store i1 false, i1* [[ACTIVE]]
102 // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
103 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
104 // CHECK: ret [[A]]* [[CAST]]
105 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
106 // CHECK-NEXT: br i1 [[ISACTIVE]]
107 // CHECK: call void @_ZdlPv(i8* [[NEW]])
108 return new A(B(), B());
109 }
110 A *f() {
111 return new A(makeB().x);
112 }
113 A *g() {
114 return new A(makeB());
115 }
116 A *h() {
117 return new A(makeB(), makeB());
118 }
119
120 A *i() {
121 // CHECK: define [[A:%.*]]* @_ZN5test11iEv()
122 // CHECK: [[X:%.*]] = alloca [[A]]*, align 8
123 // CHECK: [[ACTIVE:%.*]] = alloca i1
John McCallf4beacd2011-11-10 10:43:54 +0000124 // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8)
125 // CHECK-NEXT: store i1 true, i1* [[ACTIVE]]
John McCall824c2f52010-09-14 07:57:04 +0000126 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
127 // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]])
128 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]])
129 // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]])
130 // CHECK: store i1 false, i1* [[ACTIVE]]
131 // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8
132 // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]])
133 // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8
134 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]])
135 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]])
136 // CHECK: ret [[A]]* [[RET]]
137 // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]]
138 // CHECK-NEXT: br i1 [[ISACTIVE]]
139 // CHECK: call void @_ZdlPv(i8* [[NEW]])
140 A *x;
141 return (x = new A(makeB()), makeB(), x);
142 }
143}
144
145namespace test2 {
146 struct A {
147 A(int); A(int, int); ~A();
148 void *p;
149 void *operator new(size_t);
150 void operator delete(void*, size_t);
151 };
152
153 A *a() {
154 // CHECK: define [[A:%.*]]* @_ZN5test21aEv()
155 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8)
156 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
157 // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5)
158 // CHECK: ret [[A]]* [[CAST]]
159 // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8)
160 // CHECK: call void @_ZSt9terminatev()
161 return new A(5);
162 }
163}
164
165namespace test3 {
166 struct A {
John McCall7f9c92a2010-09-17 00:50:28 +0000167 A(int); A(int, int); A(const A&); ~A();
John McCall824c2f52010-09-14 07:57:04 +0000168 void *p;
John McCall7f9c92a2010-09-17 00:50:28 +0000169 void *operator new(size_t, void*, double);
170 void operator delete(void*, void*, double);
John McCall824c2f52010-09-14 07:57:04 +0000171 };
172
John McCall7f9c92a2010-09-17 00:50:28 +0000173 void *foo();
174 double bar();
175 A makeA(), *makeAPtr();
176
John McCall824c2f52010-09-14 07:57:04 +0000177 A *a() {
178 // CHECK: define [[A:%.*]]* @_ZN5test31aEv()
179 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
John McCall7f9c92a2010-09-17 00:50:28 +0000180 // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
181 // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]])
John McCall824c2f52010-09-14 07:57:04 +0000182 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
183 // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5)
184 // CHECK: ret [[A]]* [[CAST]]
John McCall7f9c92a2010-09-17 00:50:28 +0000185 // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]])
John McCall824c2f52010-09-14 07:57:04 +0000186 // CHECK: call void @_ZSt9terminatev()
John McCall824c2f52010-09-14 07:57:04 +0000187 return new(foo(),bar()) A(5);
188 }
John McCall7f9c92a2010-09-17 00:50:28 +0000189
190 // rdar://problem/8439196
191 A *b(bool cond) {
192
193 // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext
194 // CHECK: [[SAVED0:%.*]] = alloca i8*
195 // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8*
196 // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
John McCall7f9c92a2010-09-17 00:50:28 +0000197
198 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
John McCallf4beacd2011-11-10 10:43:54 +0000199 // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
John McCall7f9c92a2010-09-17 00:50:28 +0000200 // CHECK-NEXT: br i1 [[COND]]
201 return (cond ?
202
203 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv()
204 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]])
205 // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]]
206 // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]]
207 // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]]
208 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
Eli Friedmanb971d492012-02-16 22:45:48 +0000209 // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]])
210 // CHECK: br label
John McCall7f9c92a2010-09-17 00:50:28 +0000211 // -> cond.end
212 new(foo(),10.0) A(makeA()) :
213
Eli Friedmanb971d492012-02-16 22:45:48 +0000214 // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv()
John McCall7f9c92a2010-09-17 00:50:28 +0000215 // CHECK: br label
216 // -> cond.end
217 makeAPtr());
218
219 // cond.end:
220 // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]]
John McCall7f9c92a2010-09-17 00:50:28 +0000221 // CHECK: ret [[A]]* [[RESULT]]
222
223 // in the EH path:
224 // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]]
225 // CHECK-NEXT: br i1 [[ISACTIVE]]
226 // CHECK: [[V0:%.*]] = load i8** [[SAVED0]]
227 // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]]
228 // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]])
229 }
John McCall824c2f52010-09-14 07:57:04 +0000230}
231
232namespace test4 {
233 struct A {
234 A(int); A(int, int); ~A();
235 void *p;
236 void *operator new(size_t, void*, void*);
237 void operator delete(void*, size_t, void*, void*); // not a match
238 };
239
240 A *a() {
241 // CHECK: define [[A:%.*]]* @_ZN5test41aEv()
242 // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv()
243 // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv()
244 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]])
245 // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]*
246 // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5)
247 // CHECK-NEXT: ret [[A]]* [[CAST]]
248 extern void *foo(), *bar();
249
250 return new(foo(),bar()) A(5);
251 }
Anders Carlssonafd1edb2009-12-11 00:32:37 +0000252}
John McCall1bf58462011-02-16 08:02:54 +0000253
254// PR7908
255namespace test5 {
256 struct T { T(); ~T(); };
257
258 struct A {
259 A(const A &x, const T &t = T());
260 ~A();
261 };
262
263 void foo();
264
265 // CHECK: define void @_ZN5test54testEv()
266 // CHECK: [[EXNSLOT:%.*]] = alloca i8*
John McCall9b382dd2011-05-28 21:13:02 +0000267 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
John McCall1bf58462011-02-16 08:02:54 +0000268 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
269 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
John McCall1bf58462011-02-16 08:02:54 +0000270 // CHECK-NEXT: invoke void @_ZN5test53fooEv()
271 // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]]
272 // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
273 // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
274 // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
275 // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
276 // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]])
277 // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) nounwind
278 // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]])
279 // CHECK: call void @__cxa_end_catch()
280 void test() {
281 try {
282 foo();
283 } catch (A a) {
284 }
285 }
286}
John McCall1b93f1b2011-02-25 04:19:13 +0000287
288// PR9303: invalid assert on this
289namespace test6 {
290 bool cond();
291 void test() {
292 try {
293 lbl:
294 if (cond()) goto lbl;
295 } catch (...) {
296 }
297 }
298}
John McCallf7dcf322011-03-07 01:52:56 +0000299
300// PR9298
301namespace test7 {
302 struct A { A(); ~A(); };
303 struct B {
304 // The throw() operator means that a bad allocation is signalled
305 // with a null return, which means that the initializer is
306 // evaluated conditionally.
307 static void *operator new(size_t size) throw();
308 B(const A&, B*);
309 ~B();
310 };
311
John McCallf7dcf322011-03-07 01:52:56 +0000312 B *test() {
John McCall75f94982011-03-07 03:12:35 +0000313 // CHECK: define [[B:%.*]]* @_ZN5test74testEv()
314 // CHECK: [[OUTER_NEW:%.*]] = alloca i1
315 // CHECK-NEXT: alloca [[A:%.*]],
316 // CHECK-NEXT: alloca i8*
317 // CHECK-NEXT: alloca i32
318 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
319 // CHECK-NEXT: alloca i8*
320 // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
321 // CHECK-NEXT: alloca [[A]]
322 // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
323
John McCall75f94982011-03-07 03:12:35 +0000324 // Allocate the outer object.
325 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
326 // CHECK-NEXT: icmp eq i8* [[NEW]], null
327
328 // These stores, emitted before the outermost conditional branch,
329 // deactivate the temporary cleanups.
John McCallf4beacd2011-11-10 10:43:54 +0000330 // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]]
John McCall75f94982011-03-07 03:12:35 +0000331 // CHECK-NEXT: store i1 false, i1* [[OUTER_A]]
John McCallf4beacd2011-11-10 10:43:54 +0000332 // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]]
John McCall75f94982011-03-07 03:12:35 +0000333 // CHECK-NEXT: store i1 false, i1* [[INNER_A]]
334 // CHECK-NEXT: br i1
335
336 // We passed the first null check; activate that cleanup and continue.
337 // CHECK: store i1 true, i1* [[OUTER_NEW]]
338 // CHECK-NEXT: bitcast
339
340 // Create the first A temporary and activate that cleanup.
341 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
342 // CHECK: store i1 true, i1* [[OUTER_A]]
343
344 // Allocate the inner object.
345 // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm(
346 // CHECK-NEXT: icmp eq i8* [[NEW]], null
347 // CHECK-NEXT: br i1
348
349 // We passed the second null check; save that pointer, activate
350 // that cleanup, and continue.
351 // CHECK: store i8* [[NEW]]
352 // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]]
353 // CHECK-NEXT: bitcast
354
355 // Build the second A temporary and activate that cleanup.
356 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
357 // CHECK: store i1 true, i1* [[INNER_A]]
358
359 // Build the inner B object and deactivate the inner delete cleanup.
360 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
361 // CHECK: store i1 false, i1* [[INNER_NEW]]
362 // CHECK: phi
363
364 // Build the outer B object and deactivate the outer delete cleanup.
365 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
366 // CHECK: store i1 false, i1* [[OUTER_NEW]]
367 // CHECK: phi
John McCallb0433ee2012-09-25 06:56:03 +0000368 // CHECK-NEXT: store [[B]]*
John McCall75f94982011-03-07 03:12:35 +0000369
370 // Destroy the inner A object.
371 // CHECK-NEXT: load i1* [[INNER_A]]
372 // CHECK-NEXT: br i1
373 // CHECK: invoke void @_ZN5test71AD1Ev(
374
375 // Destroy the outer A object.
376 // CHECK: load i1* [[OUTER_A]]
377 // CHECK-NEXT: br i1
378 // CHECK: invoke void @_ZN5test71AD1Ev(
379
John McCallf7dcf322011-03-07 01:52:56 +0000380 return new B(A(), new B(A(), 0));
381 }
382}
John McCall35e4f0c2011-08-26 00:46:38 +0000383
384// Just don't crash.
385namespace test8 {
386 struct A {
John McCalla8a39bc2011-08-26 05:38:08 +0000387 // Having both of these is required to trigger the assert we're
388 // trying to avoid.
John McCall35e4f0c2011-08-26 00:46:38 +0000389 A(const A&);
John McCalla8a39bc2011-08-26 05:38:08 +0000390 A&operator=(const A&);
391
John McCall35e4f0c2011-08-26 00:46:38 +0000392 ~A();
393 };
394
395 A makeA();
396 void test() {
397 throw makeA();
398 }
Eli Friedmancf9b1f62011-09-06 18:53:03 +0000399 // CHECK: define void @_ZN5test84testEv
400}
401
402// Make sure we generate the correct code for the delete[] call which
403// happens if A::A() throws. (We were previously calling delete[] on
404// a pointer to the first array element, not the pointer returned by new[].)
405// PR10870
406namespace test9 {
407 struct A {
408 A();
409 ~A();
410 };
411 A* test() {
412 return new A[10];
413 }
414 // CHECK: define {{%.*}}* @_ZN5test94testEv
415 // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam
416 // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]])
John McCall35e4f0c2011-08-26 00:46:38 +0000417}
John McCalld8d00be2012-06-15 05:27:05 +0000418
419// In a destructor with a function-try-block, a return statement in a
420// catch handler behaves differently from running off the end of the
421// catch handler. PR13102.
422namespace test10 {
423 extern void cleanup();
424 extern bool suppress;
425
426 struct A { ~A(); };
427 A::~A() try { cleanup(); } catch (...) { return; }
428 // CHECK: define void @_ZN6test101AD1Ev(
429 // CHECK: invoke void @_ZN6test107cleanupEv()
430 // CHECK-NOT: rethrow
431 // CHECK: ret void
432
433 struct B { ~B(); };
434 B::~B() try { cleanup(); } catch (...) {}
435 // CHECK: define void @_ZN6test101BD1Ev(
436 // CHECK: invoke void @_ZN6test107cleanupEv()
437 // CHECK: call i8* @__cxa_begin_catch
438 // CHECK-NEXT: invoke void @__cxa_rethrow()
439 // CHECK: unreachable
440
441 struct C { ~C(); };
442 C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
443 // CHECK: define void @_ZN6test101CD1Ev(
444 // CHECK: invoke void @_ZN6test107cleanupEv()
445 // CHECK: call i8* @__cxa_begin_catch
446 // CHECK-NEXT: load i8* @_ZN6test108suppressE, align 1
447 // CHECK-NEXT: trunc
448 // CHECK-NEXT: br i1
449 // CHECK: call void @__cxa_end_catch()
450 // CHECK-NEXT: br label
451 // CHECK: invoke void @__cxa_rethrow()
452 // CHECK: unreachable
453}
John McCall12cc42a2013-02-01 05:11:40 +0000454
455// Ensure that an exception in a constructor destroys
456// already-constructed array members. PR14514
457namespace test11 {
458 struct A {
459 A();
460 ~A() {}
461 };
462
463 struct C {
464 A single;
465 A array[2][3];
466
467 C();
468 };
469
470 C::C() {
471 throw 0;
472 }
473 // CHECK: define void @_ZN6test111CC2Ev(
474 // CHECK: [[THIS:%.*]] = load [[C:%.*]]** {{%.*}}
475 // Construct single.
476 // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 0
477 // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]])
478 // Construct array.
479 // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 1
480 // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
481 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6
482 // CHECK-NEXT: br label
483 // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
484 // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]])
485 // CHECK: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
486 // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]]
487 // CHECK-NEXT: br i1 [[DONE]],
488 // throw 0;
489 // CHECK: invoke void @__cxa_throw(
490 // Landing pad 1, from constructor in array-initialization loop:
491 // CHECK: landingpad
492 // - First, destroy already-constructed bits of array.
493 // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]]
494 // CHECK-NEXT: br i1 [[EMPTY]]
495 // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
496 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
497 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
498 // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
499 // CHECK-NEXT: br i1 [[DONE]],
500 // - Next, chain to cleanup for single.
501 // CHECK: br label
502 // Landing pad 2, from throw site.
503 // CHECK: landingpad
504 // - First, destroy all of array.
505 // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0
506 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6
507 // CHECK-NEXT: br label
508 // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
509 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
510 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]])
511 // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]]
512 // CHECK-NEXT: br i1 [[DONE]],
513 // - Next, chain to cleanup for single.
514 // CHECK: br label
515 // Finally, the cleanup for single.
516 // CHECK: invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]])
517 // CHECK: br label
518 // CHECK: resume
519 // (After this is a terminate landingpad.)
520}