[AMDGPU][True16][CodeGen] true16 codegen pattern for v_med3_u/i16 (#121850)
[llvm-project.git] / clang / test / CodeGenCXX / exceptions.cpp
blob61cffd1023b88963f13c38b2542b274e62c53d34
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-prefixes=CHECK,CHECK11,THROWEND11 %s
3 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions -fassume-nothrow-exception-dtor | FileCheck --check-prefixes=CHECK,CHECK11,NOTHROWEND11 %s
5 // CHECK: %[[STRUCT_TEST13_A:.*]] = type { i32, i32 }
7 typedef __typeof(sizeof(0)) size_t;
9 // Declare the reserved global placement new.
10 void *operator new(size_t, void*);
12 // This just shouldn't crash.
13 namespace test0 {
14 struct allocator {
15 allocator();
16 allocator(const allocator&);
17 ~allocator();
20 void f();
21 void g(bool b, bool c) {
22 if (b) {
23 if (!c)
24 throw allocator();
26 return;
28 f();
32 namespace test1 {
33 struct A { A(int); A(int, int); ~A(); void *p; };
35 A *a() {
36 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11aEv()
37 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
38 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
39 // CHECK: ret ptr [[NEW]]
40 // CHECK: call void @_ZdlPv(ptr [[NEW]])
41 return new A(5);
44 A *b() {
45 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11bEv()
46 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
47 // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv()
48 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[FOO]])
49 // CHECK: ret ptr [[NEW]]
50 // CHECK: call void @_ZdlPv(ptr [[NEW]])
51 extern int foo();
52 return new A(foo());
55 struct B { B(); ~B(); operator int(); int x; };
56 B makeB();
58 A *c() {
59 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11cEv()
60 // CHECK: [[ACTIVE:%.*]] = alloca i1
61 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
62 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
63 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
64 // CHECK: [[T1:%.*]] = getelementptr inbounds nuw [[B:%.*]], ptr [[T0]], i32 0, i32 0
65 // CHECK-NEXT: [[T2:%.*]] = load i32, ptr [[T1]], align 4
66 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T2]])
67 // CHECK: store i1 false, ptr [[ACTIVE]]
69 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
70 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
72 // CHECK: ret ptr [[NEW]]
73 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
74 // CHECK-NEXT: br i1 [[ISACTIVE]]
75 // CHECK: call void @_ZdlPv(ptr [[NEW]])
76 return new A(B().x);
79 // Terminate landing pads should call __cxa_begin_catch first.
80 // CHECK98: define linkonce_odr hidden void @__clang_call_terminate(ptr %0) [[NI_NR_NUW:#[0-9]+]] comdat
81 // CHECK98-NEXT: [[T0:%.*]] = call ptr @__cxa_begin_catch(ptr %0) [[NUW:#[0-9]+]]
82 // CHECK98-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]]
83 // CHECK98-NEXT: unreachable
85 A *d() {
86 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11dEv()
87 // CHECK: [[ACTIVE:%.*]] = alloca i1
88 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
89 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
90 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
91 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
92 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T1]])
93 // CHECK: store i1 false, ptr [[ACTIVE]]
95 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
96 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
98 // CHECK: ret ptr [[NEW]]
99 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
100 // CHECK-NEXT: br i1 [[ISACTIVE]]
101 // CHECK: call void @_ZdlPv(ptr [[NEW]])
102 return new A(B());
105 A *e() {
106 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11eEv()
107 // CHECK: [[ACTIVE:%.*]] = alloca i1
108 // CHECK-NEXT: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
109 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
110 // CHECK-NEXT: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T0:%.*]])
111 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
112 // CHECK: invoke void @_ZN5test11BC1Ev(ptr {{[^,]*}} [[T2:%.*]])
113 // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T2]])
114 // CHECK: invoke void @_ZN5test11AC1Eii(ptr {{[^,]*}} [[NEW]], i32 [[T1]], i32 [[T3]])
115 // CHECK: store i1 false, ptr [[ACTIVE]]
117 // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
118 // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
120 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
121 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
123 // CHECK: ret ptr [[NEW]]
124 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
125 // CHECK-NEXT: br i1 [[ISACTIVE]]
126 // CHECK: call void @_ZdlPv(ptr [[NEW]])
127 return new A(B(), B());
129 A *f() {
130 return new A(makeB().x);
132 A *g() {
133 return new A(makeB());
135 A *h() {
136 return new A(makeB(), makeB());
139 A *i() {
140 // CHECK: define{{( dso_local)?}} ptr @_ZN5test11iEv()
141 // CHECK: [[X:%.*]] = alloca ptr, align 8
142 // CHECK: [[ACTIVE:%.*]] = alloca i1
143 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8)
144 // CHECK-NEXT: store i1 true, ptr [[ACTIVE]]
145 // CHECK-NEXT: invoke void @_ZN5test15makeBEv(ptr dead_on_unwind writable sret([[B:%.*]]) align 4 [[T0:%.*]])
146 // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]])
147 // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T1]])
148 // CHECK: store i1 false, ptr [[ACTIVE]]
149 // CHECK-NEXT: store ptr [[NEW]], ptr [[X]], align 8
150 // CHECK: invoke void @_ZN5test15makeBEv(ptr dead_on_unwind writable sret([[B:%.*]]) align 4 [[T2:%.*]])
151 // CHECK: [[RET:%.*]] = load ptr, ptr [[X]], align 8
153 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
154 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])
156 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
157 // CHECK11: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])
159 // CHECK: ret ptr [[RET]]
160 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]]
161 // CHECK-NEXT: br i1 [[ISACTIVE]]
162 // CHECK: call void @_ZdlPv(ptr [[NEW]])
163 A *x;
164 return (x = new A(makeB()), makeB(), x);
168 namespace test2 {
169 struct A {
170 A(int); A(int, int); ~A();
171 void *p;
172 void *operator new(size_t);
173 void operator delete(void*, size_t);
176 A *a() {
177 // CHECK: define{{( dso_local)?}} ptr @_ZN5test21aEv()
178 // CHECK: [[NEW:%.*]] = call ptr @_ZN5test21AnwEm(i64 8)
179 // CHECK-NEXT: invoke void @_ZN5test21AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
180 // CHECK: ret ptr [[NEW]]
182 // CHECK98: invoke void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)
183 // CHECK11: call void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)
185 // CHECK98: call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]
186 return new A(5);
190 namespace test3 {
191 struct A {
192 A(int); A(int, int); A(const A&); ~A();
193 void *p;
194 void *operator new(size_t, void*, double);
195 void operator delete(void*, void*, double);
198 void *foo();
199 double bar();
200 A makeA(), *makeAPtr();
202 A *a() {
203 // CHECK: define{{( dso_local)?}} ptr @_ZN5test31aEv()
204 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test33fooEv()
205 // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv()
206 // CHECK: [[NEW:%.*]] = call ptr @_ZN5test31AnwEmPvd(i64 8, ptr [[FOO]], double [[BAR]])
207 // CHECK-NEXT: invoke void @_ZN5test31AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
208 // CHECK: ret ptr [[NEW]]
210 // CHECK98: invoke void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])
211 // CHECK11: call void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])
213 // CHECK98: call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]
214 return new(foo(),bar()) A(5);
217 A *b(bool cond) {
219 // CHECK: define{{( dso_local)?}} ptr @_ZN5test31bEb(i1 zeroext
220 // CHECK: [[SAVED0:%.*]] = alloca ptr
221 // CHECK-NEXT: [[SAVED1:%.*]] = alloca ptr
222 // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
224 // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
225 // CHECK-NEXT: store i1 false, ptr [[CLEANUPACTIVE]]
226 // CHECK-NEXT: br i1 [[COND]]
227 return (cond ?
229 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test33fooEv()
230 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test31AnwEmPvd(i64 8, ptr [[FOO]], double [[CONST:.*]])
231 // CHECK-NEXT: store ptr [[NEW]], ptr [[SAVED0]]
232 // CHECK-NEXT: store ptr [[FOO]], ptr [[SAVED1]]
233 // CHECK-NEXT: store i1 true, ptr [[CLEANUPACTIVE]]
234 // CHECK-NEXT: invoke void @_ZN5test35makeAEv(ptr dead_on_unwind writable sret([[A:%.*]]) align 8 [[NEW]])
235 // CHECK: br label
236 // -> cond.end
237 new(foo(),10.0) A(makeA()) :
239 // CHECK: [[MAKE:%.*]] = call ptr @_ZN5test38makeAPtrEv()
240 // CHECK: br label
241 // -> cond.end
242 makeAPtr());
244 // cond.end:
245 // CHECK: [[RESULT:%.*]] = phi ptr {{.*}}[[NEW]]{{.*}}[[MAKE]]
246 // CHECK: ret ptr [[RESULT]]
248 // in the EH path:
249 // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[CLEANUPACTIVE]]
250 // CHECK-NEXT: br i1 [[ISACTIVE]]
251 // CHECK: [[V0:%.*]] = load ptr, ptr [[SAVED0]]
252 // CHECK-NEXT: [[V1:%.*]] = load ptr, ptr [[SAVED1]]
254 // CHECK98-NEXT: invoke void @_ZN5test31AdlEPvS1_d(ptr [[V0]], ptr [[V1]], double [[CONST]])
255 // CHECK11-NEXT: call void @_ZN5test31AdlEPvS1_d(ptr [[V0]], ptr [[V1]], double [[CONST]])
259 namespace test4 {
260 struct A {
261 A(int); A(int, int); ~A();
262 void *p;
263 void *operator new(size_t, void*, void*);
264 void operator delete(void*, size_t, void*, void*); // not a match
267 A *a() {
268 // CHECK: define{{( dso_local)?}} ptr @_ZN5test41aEv()
269 // CHECK: [[FOO:%.*]] = call ptr @_ZN5test43fooEv()
270 // CHECK-NEXT: [[BAR:%.*]] = call ptr @_ZN5test43barEv()
271 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test41AnwEmPvS1_(i64 8, ptr [[FOO]], ptr [[BAR]])
272 // CHECK-NEXT: call void @_ZN5test41AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5)
273 // CHECK-NEXT: ret ptr [[NEW]]
274 extern void *foo(), *bar();
276 return new(foo(),bar()) A(5);
280 // PR7908
281 namespace test5 {
282 struct T { T(); ~T(); };
284 struct A {
285 A(const A &x, const T &t = T());
286 ~A();
289 void foo();
291 // CHECK-LABEL: define{{.*}} void @_ZN5test54testEv()
292 // CHECK: [[EXNSLOT:%.*]] = alloca ptr
293 // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
294 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
295 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
296 // CHECK-NEXT: invoke void @_ZN5test53fooEv()
297 // CHECK: [[EXN:%.*]] = load ptr, ptr [[EXNSLOT]]
298 // CHECK-NEXT: [[ADJ:%.*]] = call ptr @__cxa_get_exception_ptr(ptr [[EXN]])
299 // CHECK-NEXT: invoke void @_ZN5test51TC1Ev(ptr {{[^,]*}} [[T]])
300 // 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]])
302 // CHECK98: invoke void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])
303 // CHECK11: call void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])
305 // CHECK98: call ptr @__cxa_begin_catch(ptr [[EXN]]) [[NUW]]
306 // CHECK98-NEXT: invoke void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[A:%.*]])
308 // CHECK: call void @__cxa_end_catch()
309 void test() {
310 try {
311 foo();
312 } catch (A a) {
317 // PR9303: invalid assert on this
318 namespace test6 {
319 bool cond();
320 void test() {
321 try {
322 lbl:
323 if (cond()) goto lbl;
324 } catch (...) {
329 // PR9298
330 namespace test7 {
331 struct A { A(); ~A(); };
332 struct B {
333 // The throw() operator means that a bad allocation is signalled
334 // with a null return, which means that the initializer is
335 // evaluated conditionally.
336 static void *operator new(size_t size) throw();
337 B(const A&, B*);
338 ~B();
341 B *test() {
342 // CHECK: define{{( dso_local)?}} ptr @_ZN5test74testEv()
343 // CHECK: [[OUTER_NEW:%.*]] = alloca i1
344 // CHECK-NEXT: alloca [[A:%.*]],
345 // CHECK-NEXT: alloca ptr
346 // CHECK-NEXT: alloca i32
347 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
348 // CHECK-NEXT: alloca ptr
349 // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
350 // CHECK-NEXT: alloca [[A:%.*]]
351 // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1
353 // Allocate the outer object.
354 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(
355 // CHECK-NEXT: icmp eq ptr [[NEW]], null
357 // These stores, emitted before the outermost conditional branch,
358 // deactivate the temporary cleanups.
359 // CHECK-NEXT: store i1 false, ptr [[OUTER_NEW]]
360 // CHECK-NEXT: store i1 false, ptr [[OUTER_A]]
361 // CHECK-NEXT: store i1 false, ptr [[INNER_NEW]]
362 // CHECK-NEXT: store i1 false, ptr [[INNER_A]]
363 // CHECK-NEXT: br i1
365 // We passed the first null check; activate that cleanup and continue.
366 // CHECK: store i1 true, ptr [[OUTER_NEW]]
368 // Create the first A temporary and activate that cleanup.
369 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
370 // CHECK: store i1 true, ptr [[OUTER_A]]
372 // Allocate the inner object.
373 // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(
374 // CHECK-NEXT: icmp eq ptr [[NEW]], null
375 // CHECK-NEXT: br i1
377 // We passed the second null check; save that pointer, activate
378 // that cleanup, and continue.
379 // CHECK: store ptr [[NEW]]
380 // CHECK-NEXT: store i1 true, ptr [[INNER_NEW]]
382 // Build the second A temporary and activate that cleanup.
383 // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(
384 // CHECK: store i1 true, ptr [[INNER_A]]
386 // Build the inner B object and deactivate the inner delete cleanup.
387 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
388 // CHECK: store i1 false, ptr [[INNER_NEW]]
389 // CHECK: phi
391 // Build the outer B object and deactivate the outer delete cleanup.
392 // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_(
393 // CHECK: store i1 false, ptr [[OUTER_NEW]]
394 // CHECK: phi
395 // CHECK-NEXT: store ptr
397 // Destroy the inner A object.
398 // CHECK-NEXT: load i1, ptr [[INNER_A]]
399 // CHECK-NEXT: br i1
401 // CHECK98: invoke void @_ZN5test71AD1Ev(
402 // CHECK11: call void @_ZN5test71AD1Ev(
404 // Destroy the outer A object.
405 // CHECK: load i1, ptr [[OUTER_A]]
406 // CHECK-NEXT: br i1
408 // CHECK98: invoke void @_ZN5test71AD1Ev(
409 // CHECK11: call void @_ZN5test71AD1Ev(
411 return new B(A(), new B(A(), 0));
415 // Just don't crash.
416 namespace test8 {
417 struct A {
418 // Having both of these is required to trigger the assert we're
419 // trying to avoid.
420 A(const A&);
421 A&operator=(const A&);
423 ~A();
426 A makeA();
427 void test() {
428 throw makeA();
430 // CHECK-LABEL: define{{.*}} void @_ZN5test84testEv
433 // Make sure we generate the correct code for the delete[] call which
434 // happens if A::A() throws. (We were previously calling delete[] on
435 // a pointer to the first array element, not the pointer returned by new[].)
436 // PR10870
437 namespace test9 {
438 struct A {
439 A();
440 ~A();
442 A* test() {
443 return new A[10];
445 // CHECK: define{{.*}} ptr @_ZN5test94testEv
446 // CHECK: [[TEST9_NEW:%.*]] = call noalias nonnull ptr @_Znam
447 // CHECK: call void @_ZdaPv(ptr [[TEST9_NEW]])
450 // In a destructor with a function-try-block, a return statement in a
451 // catch handler behaves differently from running off the end of the
452 // catch handler. PR13102.
453 namespace test10 {
454 extern void cleanup();
455 extern bool suppress;
457 struct A { ~A(); };
458 A::~A() try { cleanup(); } catch (...) { return; }
459 // CHECK-LABEL: define{{.*}} void @_ZN6test101AD1Ev(
460 // CHECK: invoke void @_ZN6test107cleanupEv()
461 // CHECK-NOT: rethrow
462 // CHECK: ret void
464 struct B { ~B(); };
465 B::~B() try { cleanup(); } catch (...) {}
466 // CHECK-LABEL: define{{.*}} void @_ZN6test101BD1Ev(
467 // CHECK: invoke void @_ZN6test107cleanupEv()
468 // CHECK: call ptr @__cxa_begin_catch
469 // CHECK-NEXT: invoke void @__cxa_rethrow()
470 // CHECK: unreachable
472 struct C { ~C(); };
473 C::~C() try { cleanup(); } catch (...) { if (suppress) return; }
474 // CHECK-LABEL: define{{.*}} void @_ZN6test101CD1Ev(
475 // CHECK: invoke void @_ZN6test107cleanupEv()
476 // CHECK: call ptr @__cxa_begin_catch
477 // CHECK-NEXT: load i8, ptr @_ZN6test108suppressE, align 1
478 // CHECK-NEXT: trunc
479 // CHECK-NEXT: br i1
481 // CHECK98: call void @__cxa_end_catch()
482 // CHECK98-NEXT: br label
483 // THROWEND11: invoke void @__cxa_end_catch()
484 // THROWEND11-NEXT: to label %invoke.cont[[#]] unwind label %terminate.lpad
485 // NOTHROWEND11: call void @__cxa_end_catch()
486 // NOTHROWEND11-NEXT: br label %try.cont
488 // CHECK: invoke void @__cxa_rethrow()
489 // CHECK: unreachable
491 // CHECK: terminate.lpad:
492 // CHECK: call void @__clang_call_terminate(
495 // Ensure that an exception in a constructor destroys
496 // already-constructed array members. PR14514
497 namespace test11 {
498 struct A {
499 A();
500 ~A() {}
503 struct C {
504 A single;
505 A array[2][3];
507 C();
510 C::C() {
511 throw 0;
513 // CHECK-LABEL: define{{.*}} void @_ZN6test111CC2Ev(
514 // CHECK: [[THIS:%.*]] = load ptr, ptr {{%.*}}
515 // Construct single.
516 // CHECK-NEXT: call void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[THIS]])
517 // Construct array.
518 // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw [[C:%.*]], ptr [[THIS]], i32 0, i32 1
519 // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0
520 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6
521 // CHECK-NEXT: br label
522 // CHECK: [[CUR:%.*]] = phi ptr [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
523 // CHECK-NEXT: invoke void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[CUR]])
524 // CHECK: [[NEXT]] = getelementptr inbounds [[A:%.*]], ptr [[CUR]], i64 1
525 // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[ARRAYEND]]
526 // CHECK-NEXT: br i1 [[DONE]],
527 // throw 0;
528 // CHECK: invoke void @__cxa_throw(
529 // Landing pad 1, from constructor in array-initialization loop:
530 // CHECK: landingpad
531 // - First, destroy already-constructed bits of array.
532 // CHECK: [[EMPTY:%.*]] = icmp eq ptr [[ARRAYBEGIN]], [[CUR]]
533 // CHECK-NEXT: br i1 [[EMPTY]]
534 // CHECK: [[AFTER:%.*]] = phi ptr [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
535 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A:%.*]], ptr [[AFTER]], i64 -1
537 // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
538 // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
540 // CHECK: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
541 // CHECK-NEXT: br i1 [[DONE]],
542 // - Next, chain to cleanup for single.
543 // CHECK: br label
544 // Landing pad 2, from throw site.
545 // CHECK: landingpad
546 // - First, destroy all of array.
547 // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0
548 // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6
549 // CHECK-NEXT: br label
550 // CHECK: [[AFTER:%.*]] = phi ptr [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
551 // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], ptr [[AFTER]], i64 -1
553 // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
554 // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])
556 // CHECK: [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]
557 // CHECK-NEXT: br i1 [[DONE]],
558 // - Next, chain to cleanup for single.
559 // CHECK: br label
560 // Finally, the cleanup for single.
562 // CHECK98: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])
563 // CHECK11: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])
565 // CHECK: br label
566 // CHECK: resume
567 // (After this is a terminate landingpad.)
570 namespace test12 {
571 struct A {
572 void operator delete(void *, void *);
573 A();
576 A *test(void *ptr) {
577 return new (ptr) A();
579 // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(
580 // CHECK: [[PTR:%.*]] = load ptr, ptr
581 // CHECK-NEXT: invoke void @_ZN6test121AC1Ev(ptr {{[^,]*}} [[PTR]])
582 // CHECK: ret ptr [[PTR]]
584 // CHECK98: invoke void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])
585 // CHECK11: call void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])
588 namespace test13 {
590 struct A {
591 A();
592 ~A();
593 int a, b;
596 // CHECK: define{{.*}} void @_ZN6test134testEi(
597 // CHECK: %[[REF_TMP:.*]] = alloca %[[STRUCT_TEST13_A]], align 4
598 // CHECK: %[[CLEANUP_COND:.*]] = alloca i1, align 1
599 // CHECK: %[[REF_TMP1:.*]] = alloca %[[STRUCT_TEST13_A]], align 4
600 // CHECK: %[[CLEANUP_COND2:.*]] = alloca i1, align 1
602 // CHECK: call void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP]])
603 // CHECK: store i1 true, ptr %[[CLEANUP_COND]], align 1
604 // CHECK: br
606 // CHECK: invoke void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP1]])
608 // CHECK: store i1 true, ptr %[[CLEANUP_COND2]], align 1
609 // CHECK: br
611 // Check the flag before destructing the temporary.
613 // CHECK: landingpad { ptr, i32 }
614 // CHECK: %[[CLEANUP_IS_ACTIVE:.*]] = load i1, ptr %[[CLEANUP_COND]], align 1
615 // CHECK: br i1 %[[CLEANUP_IS_ACTIVE]],
617 // CHECK: void @_ZN6test131AD1Ev(ptr {{[^,]*}} %[[REF_TMP]])
619 void test(int c) {
620 const A &s = c ? static_cast<const A &>(A()) : static_cast<const A &>(A());
625 // CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} }