Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / exceptions.cpp
blob8301c68b8fbd254f672c69f78085c3080c15bf64
1 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++98 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
2 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
4 // CHECK: %[[STRUCT_TEST13_A:.*]] = type { i32, i32 }
6 typedef __typeof(sizeof(0)) size_t;
8 // Declare the reserved global placement new.
9 void *operator new(size_t, void*);
11 // This just shouldn't crash.
12 namespace test0 {
13 struct allocator {
14 allocator();
15 allocator(const allocator&);
16 ~allocator();
19 void f();
20 void g(bool b, bool c) {
21 if (b) {
22 if (!c)
23 throw allocator();
25 return;
27 f();
31 namespace test1 {
32 struct A { A(int); A(int, int); ~A(); void *p; };
34 A *a() {
35 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11aEv()
36 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
37 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
38 // CHECK: ret ptr [[NEW]]
39 // CHECK: call void @_ZdlPv(ptr [[NEW]])
40 return new A(5);
43 A *b() {
44 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11bEv()
45 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
46 // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
47 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[FOO]])
48 // CHECK: ret ptr [[NEW]]
49 // CHECK: call void @_ZdlPv(ptr [[NEW]])
50 extern int foo();
51 return new A(foo());
54 struct B { B(); ~B(); operator int(); int x; };
55 B makeB();
57 A *c() {
58 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11cEv()
59 // CHECK: [[ACTIVE:%.*]] = alloca i1
60 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
61 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
62 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
63 // CHECK: [[T1:%.*]] = getelementptr inbounds [[B:%.*]], ptr [[T0]], i32 0, i32 0
64 // CHECK-NEXT: [[T2:%.*]] = load i32, ptr [[T1]], align 4
65 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T2]])
66 // CHECK: store i1 false, ptr [[ACTIVE]]
68 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
69 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
71 // CHECK: ret ptr [[NEW]]
72 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
73 // CHECK-NEXT: br i1 [[ISACTIVE]]
74 // CHECK: call void @_ZdlPv(ptr [[NEW]])
75 return new A(B().x);
78 // Terminate landing pads should call __cxa_begin_catch first.
79 // CHECK98: define linkonce_odr hidden void @__clang_call_terminate(ptr %0) [[NI_NR_NUW:#[0-9]+]] comdat
80 // CHECK98-NEXT: [[T0:%.*]] = call ptr @__cxa_begin_catch(ptr %0) [[NUW:#[0-9]+]]
81 // CHECK98-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
82 // CHECK98-NEXT: unreachable
84 A *d() {
85 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11dEv()
86 // CHECK: [[ACTIVE:%.*]] = alloca i1
87 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
88 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
89 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
90 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
91 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T1]])
92 // CHECK: store i1 false, ptr [[ACTIVE]]
94 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
95 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
97 // CHECK: ret ptr [[NEW]]
98 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
99 // CHECK-NEXT: br i1 [[ISACTIVE]]
100 // CHECK: call void @_ZdlPv(ptr [[NEW]])
101 return new A(B());
104 A *e() {
105 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11eEv()
106 // CHECK: [[ACTIVE:%.*]] = alloca i1
107 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
108 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
109 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
110 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
111 // CHECK: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T2:%.*]])
112 // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T2]])
113 // CHECK: invoke void @_ZN5test11AC1Eii(ptr {{[^,]*}} [[NEW]], i32 [[T1]], i32 [[T3]])
114 // CHECK: store i1 false, ptr [[ACTIVE]]
116 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
117 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
119 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
120 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
122 // CHECK: ret ptr [[NEW]]
123 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
124 // CHECK-NEXT: br i1 [[ISACTIVE]]
125 // CHECK: call void @_ZdlPv(ptr [[NEW]])
126 return new A(B(), B());
128 A *f() {
129 return new A(makeB().x);
131 A *g() {
132 return new A(makeB());
134 A *h() {
135 return new A(makeB(), makeB());
138 A *i() {
139 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11iEv()
140 // CHECK: [[X:%.*]] = alloca ptr, align 8
141 // CHECK: [[ACTIVE:%.*]] = alloca i1
142 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
143 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
144 // CHECK-NEXT: invoke void @_ZN5test15makeBEv(ptr sret([[B:%.*]]) align 4 [[T0:%.*]])
145 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
146 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T1]])
147 // CHECK: store i1 false, ptr [[ACTIVE]]
148 // CHECK-NEXT: store ptr [[NEW]], ptr [[X]], align 8
149 // CHECK: invoke void @_ZN5test15makeBEv(ptr sret([[B:%.*]]) align 4 [[T2:%.*]])
150 // CHECK: [[RET:%.*]] = load ptr, ptr [[X]], align 8
152 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
153 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
155 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
156 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
158 // CHECK: ret ptr [[RET]]
159 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
160 // CHECK-NEXT: br i1 [[ISACTIVE]]
161 // CHECK: call void @_ZdlPv(ptr [[NEW]])
162 A *x;
163 return (x = new A(makeB()), makeB(), x);
167 namespace test2 {
168 struct A {
169 A(int); A(int, int); ~A();
170 void *p;
171 void *operator new(size_t);
172 void operator delete(void*, size_t);
175 A *a() {
176 // CHECK: define{{( dso_local)?}} ptr @_ZN5test21aEv()
177 // CHECK: [[NEW:%.*]] = call ptr @_ZN5test21AnwEm(i64 8)
178 // CHECK-NEXT: invoke void @_ZN5test21AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
179 // CHECK: ret ptr [[NEW]]
181 // CHECK98: invoke void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)
182 // CHECK11: call void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)
184 // CHECK98: call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]
185 return new A(5);
189 namespace test3 {
190 struct A {
191 A(int); A(int, int); A(const A&); ~A();
192 void *p;
193 void *operator new(size_t, void*, double);
194 void operator delete(void*, void*, double);
197 void *foo();
198 double bar();
199 A makeA(), *makeAPtr();
201 A *a() {
202 // CHECK: define{{( dso_local)?}} ptr @_ZN5test31aEv()
203 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test33fooEv()
204 // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
205 // CHECK: [[NEW:%.*]] = call ptr @_ZN5test31AnwEmPvd(i64 8, ptr [[FOO]], double [[BAR]])
206 // CHECK-NEXT: invoke void @_ZN5test31AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
207 // CHECK: ret ptr [[NEW]]
209 // CHECK98: invoke void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])
210 // CHECK11: call void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])
212 // CHECK98: call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]
213 return new(foo(),bar()) A(5);
216 A *b(bool cond) {
218 // CHECK: define{{( dso_local)?}} ptr @_ZN5test31bEb(i1 zeroext
219 // CHECK: [[SAVED0:%.*]] = alloca ptr
220 // CHECK-NEXT: [[SAVED1:%.*]] = alloca ptr
221 // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
223 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
224 // CHECK-NEXT: store i1 false, ptr [[CLEANUPACTIVE]]
225 // CHECK-NEXT: br i1 [[COND]]
226 return (cond ?
228 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test33fooEv()
229 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test31AnwEmPvd(i64 8, ptr [[FOO]], double [[CONST:.*]])
230 // CHECK-NEXT: store ptr [[NEW]], ptr [[SAVED0]]
231 // CHECK-NEXT: store ptr [[FOO]], ptr [[SAVED1]]
232 // CHECK-NEXT: store i1 true, ptr [[CLEANUPACTIVE]]
233 // CHECK-NEXT: invoke void @_ZN5test35makeAEv(ptr sret([[A:%.*]]) align 8 [[NEW]])
234 // CHECK: br label
235 // -> cond.end
236 new(foo(),10.0) A(makeA()) :
238 // CHECK: [[MAKE:%.*]] = call ptr @_ZN5test38makeAPtrEv()
239 // CHECK: br label
240 // -> cond.end
241 makeAPtr());
243 // cond.end:
244 // CHECK: [[RESULT:%.*]] = phi ptr {{.*}}[[NEW]]{{.*}}[[MAKE]]
245 // CHECK: ret ptr [[RESULT]]
247 // in the EH path:
248 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[CLEANUPACTIVE]]
249 // CHECK-NEXT: br i1 [[ISACTIVE]]
250 // CHECK: [[V0:%.*]] = load ptr, ptr [[SAVED0]]
251 // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[SAVED1]]
253 // CHECK98-NEXT: invoke void @_ZN5test31AdlEPvS1_d(ptr [[V0]], ptr [[V1]], double [[CONST]])
254 // CHECK11-NEXT: call void @_ZN5test31AdlEPvS1_d(ptr [[V0]], ptr [[V1]], double [[CONST]])
258 namespace test4 {
259 struct A {
260 A(int); A(int, int); ~A();
261 void *p;
262 void *operator new(size_t, void*, void*);
263 void operator delete(void*, size_t, void*, void*); // not a match
266 A *a() {
267 // CHECK: define{{( dso_local)?}} ptr @_ZN5test41aEv()
268 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test43fooEv()
269 // CHECK-NEXT: [[BAR:%.*]] = call ptr @_ZN5test43barEv()
270 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test41AnwEmPvS1_(i64 8, ptr [[FOO]], ptr [[BAR]])
271 // CHECK-NEXT: call void @_ZN5test41AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
272 // CHECK-NEXT: ret ptr [[NEW]]
273 extern void *foo(), *bar();
275 return new(foo(),bar()) A(5);
279 // PR7908
280 namespace test5 {
281 struct T { T(); ~T(); };
283 struct A {
284 A(const A &x, const T &t = T());
285 ~A();
288 void foo();
290 // CHECK-LABEL: define{{.*}} void @_ZN5test54testEv()
291 // CHECK: [[EXNSLOT:%.*]] = alloca ptr
292 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
293 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
294 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
295 // CHECK-NEXT: invoke void @_ZN5test53fooEv()
296 // CHECK: [[EXN:%.*]] = load ptr, ptr [[EXNSLOT]]
297 // CHECK-NEXT: [[ADJ:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]])
298 // CHECK-NEXT: invoke void @_ZN5test51TC1Ev(ptr {{[^,]*}} [[T]])
299 // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE(ptr {{[^,]*}} [[A:%.*]], ptr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[ADJ]], ptr nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[T]])
301 // CHECK98: invoke void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])
302 // CHECK11: call void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])
304 // CHECK98: call ptr @__cxa_begin_catch(ptr [[EXN]]) [[NUW]]
305 // CHECK98-NEXT: invoke void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[A:%.*]])
307 // CHECK: call void @__cxa_end_catch()
308 void test() {
309 try {
310 foo();
311 } catch (A a) {
316 // PR9303: invalid assert on this
317 namespace test6 {
318 bool cond();
319 void test() {
320 try {
321 lbl:
322 if (cond()) goto lbl;
323 } catch (...) {
328 // PR9298
329 namespace test7 {
330 struct A { A(); ~A(); };
331 struct B {
332 // The throw() operator means that a bad allocation is signalled
333 // with a null return, which means that the initializer is
334 // evaluated conditionally.
335 static void *operator new(size_t size) throw();
336 B(const A&, B*);
337 ~B();
340 B *test() {
341 // CHECK: define{{( dso_local)?}} ptr @_ZN5test74testEv()
342 // CHECK: [[OUTER_NEW:%.*]] = alloca i1
343 // CHECK-NEXT: alloca [[A:%.*]],
344 // CHECK-NEXT: alloca ptr
345 // CHECK-NEXT: alloca i32
346 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
347 // CHECK-NEXT: alloca ptr
348 // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
349 // CHECK-NEXT: alloca [[A:%.*]]
350 // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
352 // Allocate the outer object.
353 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(
354 // CHECK-NEXT: icmp eq ptr [[NEW]], null
356 // These stores, emitted before the outermost conditional branch,
357 // deactivate the temporary cleanups.
358 // CHECK-NEXT: store i1 false, ptr [[OUTER_NEW]]
359 // CHECK-NEXT: store i1 false, ptr [[OUTER_A]]
360 // CHECK-NEXT: store i1 false, ptr [[INNER_NEW]]
361 // CHECK-NEXT: store i1 false, ptr [[INNER_A]]
362 // CHECK-NEXT: br i1
364 // We passed the first null check; activate that cleanup and continue.
365 // CHECK: store i1 true, ptr [[OUTER_NEW]]
367 // Create the first A temporary and activate that cleanup.
368 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
369 // CHECK: store i1 true, ptr [[OUTER_A]]
371 // Allocate the inner object.
372 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(
373 // CHECK-NEXT: icmp eq ptr [[NEW]], null
374 // CHECK-NEXT: br i1
376 // We passed the second null check; save that pointer, activate
377 // that cleanup, and continue.
378 // CHECK: store ptr [[NEW]]
379 // CHECK-NEXT: store i1 true, ptr [[INNER_NEW]]
381 // Build the second A temporary and activate that cleanup.
382 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
383 // CHECK: store i1 true, ptr [[INNER_A]]
385 // Build the inner B object and deactivate the inner delete cleanup.
386 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
387 // CHECK: store i1 false, ptr [[INNER_NEW]]
388 // CHECK: phi
390 // Build the outer B object and deactivate the outer delete cleanup.
391 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
392 // CHECK: store i1 false, ptr [[OUTER_NEW]]
393 // CHECK: phi
394 // CHECK-NEXT: store ptr
396 // Destroy the inner A object.
397 // CHECK-NEXT: load i1, ptr [[INNER_A]]
398 // CHECK-NEXT: br i1
400 // CHECK98: invoke void @_ZN5test71AD1Ev(
401 // CHECK11: call void @_ZN5test71AD1Ev(
403 // Destroy the outer A object.
404 // CHECK: load i1, ptr [[OUTER_A]]
405 // CHECK-NEXT: br i1
407 // CHECK98: invoke void @_ZN5test71AD1Ev(
408 // CHECK11: call void @_ZN5test71AD1Ev(
410 return new B(A(), new B(A(), 0));
414 // Just don't crash.
415 namespace test8 {
416 struct A {
417 // Having both of these is required to trigger the assert we're
418 // trying to avoid.
419 A(const A&);
420 A&operator=(const A&);
422 ~A();
425 A makeA();
426 void test() {
427 throw makeA();
429 // CHECK-LABEL: define{{.*}} void @_ZN5test84testEv
432 // Make sure we generate the correct code for the delete[] call which
433 // happens if A::A() throws. (We were previously calling delete[] on
434 // a pointer to the first array element, not the pointer returned by new[].)
435 // PR10870
436 namespace test9 {
437 struct A {
438 A();
439 ~A();
441 A* test() {
442 return new A[10];
444 // CHECK: define{{.*}} ptr @_ZN5test94testEv
445 // CHECK: [[TEST9_NEW:%.*]] = call noalias nonnull ptr @_Znam
446 // CHECK: call void @_ZdaPv(ptr [[TEST9_NEW]])
449 // In a destructor with a function-try-block, a return statement in a
450 // catch handler behaves differently from running off the end of the
451 // catch handler. PR13102.
452 namespace test10 {
453 extern void cleanup();
454 extern bool suppress;
456 struct A { ~A(); };
457 A::~A() try { cleanup(); } catch (...) { return; }
458 // CHECK-LABEL: define{{.*}} void @_ZN6test101AD1Ev(
459 // CHECK: invoke void @_ZN6test107cleanupEv()
460 // CHECK-NOT: rethrow
461 // CHECK: ret void
463 struct B { ~B(); };
464 B::~B() try { cleanup(); } catch (...) {}
465 // CHECK-LABEL: define{{.*}} void @_ZN6test101BD1Ev(
466 // CHECK: invoke void @_ZN6test107cleanupEv()
467 // CHECK: call ptr @__cxa_begin_catch
468 // CHECK-NEXT: invoke void @__cxa_rethrow()
469 // CHECK: unreachable
471 struct C { ~C(); };
472 C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
473 // CHECK-LABEL: define{{.*}} void @_ZN6test101CD1Ev(
474 // CHECK: invoke void @_ZN6test107cleanupEv()
475 // CHECK: call ptr @__cxa_begin_catch
476 // CHECK-NEXT: load i8, ptr @_ZN6test108suppressE, align 1
477 // CHECK-NEXT: trunc
478 // CHECK-NEXT: br i1
480 // CHECK98: call void @__cxa_end_catch()
481 // CHECK98-NEXT: br label
482 // CHECK11: invoke void @__cxa_end_catch()
483 // CHECK11-NEXT: to label
485 // CHECK: invoke void @__cxa_rethrow()
486 // CHECK: unreachable
489 // Ensure that an exception in a constructor destroys
490 // already-constructed array members. PR14514
491 namespace test11 {
492 struct A {
493 A();
494 ~A() {}
497 struct C {
498 A single;
499 A array[2][3];
501 C();
504 C::C() {
505 throw 0;
507 // CHECK-LABEL: define{{.*}} void @_ZN6test111CC2Ev(
508 // CHECK: [[THIS:%.*]] = load ptr, ptr {{%.*}}
509 // Construct single.
510 // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C:%.*]], ptr [[THIS]], i32 0, i32 0
511 // CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[SINGLE]])
512 // Construct array.
513 // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C:%.*]], ptr [[THIS]], i32 0, i32 1
514 // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0
515 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6
516 // CHECK-NEXT: br label
517 // CHECK: [[CUR:%.*]] = phi ptr [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
518 // CHECK-NEXT: invoke void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[CUR]])
519 // CHECK: [[NEXT]] = getelementptr inbounds [[A:%.*]], ptr [[CUR]], i64 1
520 // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[ARRAYEND]]
521 // CHECK-NEXT: br i1 [[DONE]],
522 // throw 0;
523 // CHECK: invoke void @__cxa_throw(
524 // Landing pad 1, from constructor in array-initialization loop:
525 // CHECK: landingpad
526 // - First, destroy already-constructed bits of array.
527 // CHECK: [[EMPTY:%.*]] = icmp eq ptr [[ARRAYBEGIN]], [[CUR]]
528 // CHECK-NEXT: br i1 [[EMPTY]]
529 // CHECK: [[AFTER:%.*]] = phi ptr [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
530 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A:%.*]], ptr [[AFTER]], i64 -1
532 // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
533 // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
535 // CHECK: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
536 // CHECK-NEXT: br i1 [[DONE]],
537 // - Next, chain to cleanup for single.
538 // CHECK: br label
539 // Landing pad 2, from throw site.
540 // CHECK: landingpad
541 // - First, destroy all of array.
542 // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0
543 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6
544 // CHECK-NEXT: br label
545 // CHECK: [[AFTER:%.*]] = phi ptr [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
546 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], ptr [[AFTER]], i64 -1
548 // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
549 // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
551 // CHECK: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
552 // CHECK-NEXT: br i1 [[DONE]],
553 // - Next, chain to cleanup for single.
554 // CHECK: br label
555 // Finally, the cleanup for single.
557 // CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]])
558 // CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[SINGLE]])
560 // CHECK: br label
561 // CHECK: resume
562 // (After this is a terminate landingpad.)
565 namespace test12 {
566 struct A {
567 void operator delete(void *, void *);
568 A();
571 A *test(void *ptr) {
572 return new (ptr) A();
574 // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(
575 // CHECK: [[PTR:%.*]] = load ptr, ptr
576 // CHECK-NEXT: invoke void @_ZN6test121AC1Ev(ptr {{[^,]*}} [[PTR]])
577 // CHECK: ret ptr [[PTR]]
579 // CHECK98: invoke void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])
580 // CHECK11: call void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])
583 namespace test13 {
585 struct A {
586 A();
587 ~A();
588 int a, b;
591 // CHECK: define{{.*}} void @_ZN6test134testEi(
592 // CHECK: %[[REF_TMP:.*]] = alloca %[[STRUCT_TEST13_A]], align 4
593 // CHECK: %[[CLEANUP_COND:.*]] = alloca i1, align 1
594 // CHECK: %[[REF_TMP1:.*]] = alloca %[[STRUCT_TEST13_A]], align 4
595 // CHECK: %[[CLEANUP_COND2:.*]] = alloca i1, align 1
597 // CHECK: call void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP]])
598 // CHECK: store i1 true, ptr %[[CLEANUP_COND]], align 1
599 // CHECK: br
601 // CHECK: invoke void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP1]])
603 // CHECK: store i1 true, ptr %[[CLEANUP_COND2]], align 1
604 // CHECK: br
606 // Check the flag before destructing the temporary.
608 // CHECK: landingpad { ptr, i32 }
609 // CHECK: %[[CLEANUP_IS_ACTIVE:.*]] = load i1, ptr %[[CLEANUP_COND]], align 1
610 // CHECK: br i1 %[[CLEANUP_IS_ACTIVE]],
612 // CHECK: void @_ZN6test131AD1Ev(ptr {{[^,]*}} %[[REF_TMP]])
614 void test(int c) {
615 const A &s = c ? static_cast<const A &>(A()) : static_cast<const A &>(A());
620 // CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} }