1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s 2*f4a2713aSLionel Sambuc 3*f4a2713aSLionel Sambuc typedef typeof(sizeof(0)) size_t; 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel Sambuc // This just shouldn't crash. 6*f4a2713aSLionel Sambuc namespace test0 { 7*f4a2713aSLionel Sambuc struct allocator { 8*f4a2713aSLionel Sambuc allocator(); 9*f4a2713aSLionel Sambuc allocator(const allocator&); 10*f4a2713aSLionel Sambuc ~allocator(); 11*f4a2713aSLionel Sambuc }; 12*f4a2713aSLionel Sambuc 13*f4a2713aSLionel Sambuc void f(); 14*f4a2713aSLionel Sambuc void g(bool b, bool c) { 15*f4a2713aSLionel Sambuc if (b) { 16*f4a2713aSLionel Sambuc if (!c) 17*f4a2713aSLionel Sambuc throw allocator(); 18*f4a2713aSLionel Sambuc 19*f4a2713aSLionel Sambuc return; 20*f4a2713aSLionel Sambuc } 21*f4a2713aSLionel Sambuc f(); 22*f4a2713aSLionel Sambuc } 23*f4a2713aSLionel Sambuc } 24*f4a2713aSLionel Sambuc 25*f4a2713aSLionel Sambuc namespace test1 { 26*f4a2713aSLionel Sambuc struct A { A(int); A(int, int); ~A(); void *p; }; 27*f4a2713aSLionel Sambuc 28*f4a2713aSLionel Sambuc A *a() { 29*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11aEv() 30*f4a2713aSLionel Sambuc // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 31*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 32*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 5) 33*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 34*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 35*f4a2713aSLionel Sambuc return new A(5); 36*f4a2713aSLionel Sambuc } 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc A *b() { 39*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11bEv() 40*f4a2713aSLionel Sambuc // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 41*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 42*f4a2713aSLionel Sambuc // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv() 43*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[FOO]]) 44*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 45*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 46*f4a2713aSLionel Sambuc extern int foo(); 47*f4a2713aSLionel Sambuc return new A(foo()); 48*f4a2713aSLionel Sambuc } 49*f4a2713aSLionel Sambuc 50*f4a2713aSLionel Sambuc struct B { B(); ~B(); operator int(); int x; }; 51*f4a2713aSLionel Sambuc B makeB(); 52*f4a2713aSLionel Sambuc 53*f4a2713aSLionel Sambuc A *c() { 54*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11cEv() 55*f4a2713aSLionel Sambuc // CHECK: [[ACTIVE:%.*]] = alloca i1 56*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 57*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] 58*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 59*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) 60*f4a2713aSLionel Sambuc // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0 61*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4 62*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]]) 63*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[ACTIVE]] 64*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) 65*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 66*f4a2713aSLionel Sambuc // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] 67*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[ISACTIVE]] 68*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 69*f4a2713aSLionel Sambuc return new A(B().x); 70*f4a2713aSLionel Sambuc } 71*f4a2713aSLionel Sambuc 72*f4a2713aSLionel Sambuc // rdar://11904428 73*f4a2713aSLionel Sambuc // Terminate landing pads should call __cxa_begin_catch first. 74*f4a2713aSLionel Sambuc // CHECK: define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] 75*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]] 76*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]] 77*f4a2713aSLionel Sambuc // CHECK-NEXT: unreachable 78*f4a2713aSLionel Sambuc 79*f4a2713aSLionel Sambuc A *d() { 80*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11dEv() 81*f4a2713aSLionel Sambuc // CHECK: [[ACTIVE:%.*]] = alloca i1 82*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 83*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] 84*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 85*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) 86*f4a2713aSLionel Sambuc // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) 87*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]]) 88*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[ACTIVE]] 89*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) 90*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 91*f4a2713aSLionel Sambuc // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] 92*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[ISACTIVE]] 93*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 94*f4a2713aSLionel Sambuc return new A(B()); 95*f4a2713aSLionel Sambuc } 96*f4a2713aSLionel Sambuc 97*f4a2713aSLionel Sambuc A *e() { 98*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11eEv() 99*f4a2713aSLionel Sambuc // CHECK: [[ACTIVE:%.*]] = alloca i1 100*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 101*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] 102*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 103*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) 104*f4a2713aSLionel Sambuc // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) 105*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11BC1Ev([[B]]* [[T2:%.*]]) 106*f4a2713aSLionel Sambuc // CHECK: [[T3:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T2]]) 107*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11AC1Eii([[A]]* [[CAST]], i32 [[T1]], i32 [[T3]]) 108*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[ACTIVE]] 109*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) 110*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) 111*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 112*f4a2713aSLionel Sambuc // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] 113*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[ISACTIVE]] 114*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 115*f4a2713aSLionel Sambuc return new A(B(), B()); 116*f4a2713aSLionel Sambuc } 117*f4a2713aSLionel Sambuc A *f() { 118*f4a2713aSLionel Sambuc return new A(makeB().x); 119*f4a2713aSLionel Sambuc } 120*f4a2713aSLionel Sambuc A *g() { 121*f4a2713aSLionel Sambuc return new A(makeB()); 122*f4a2713aSLionel Sambuc } 123*f4a2713aSLionel Sambuc A *h() { 124*f4a2713aSLionel Sambuc return new A(makeB(), makeB()); 125*f4a2713aSLionel Sambuc } 126*f4a2713aSLionel Sambuc 127*f4a2713aSLionel Sambuc A *i() { 128*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test11iEv() 129*f4a2713aSLionel Sambuc // CHECK: [[X:%.*]] = alloca [[A]]*, align 8 130*f4a2713aSLionel Sambuc // CHECK: [[ACTIVE:%.*]] = alloca i1 131*f4a2713aSLionel Sambuc // CHECK: [[NEW:%.*]] = call noalias i8* @_Znwm(i64 8) 132*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] 133*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 134*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T0:%.*]]) 135*f4a2713aSLionel Sambuc // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv([[B]]* [[T0]]) 136*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T1]]) 137*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[ACTIVE]] 138*f4a2713aSLionel Sambuc // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8 139*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]]) 140*f4a2713aSLionel Sambuc // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8 141*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) 142*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) 143*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[RET]] 144*f4a2713aSLionel Sambuc // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] 145*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[ISACTIVE]] 146*f4a2713aSLionel Sambuc // CHECK: call void @_ZdlPv(i8* [[NEW]]) 147*f4a2713aSLionel Sambuc A *x; 148*f4a2713aSLionel Sambuc return (x = new A(makeB()), makeB(), x); 149*f4a2713aSLionel Sambuc } 150*f4a2713aSLionel Sambuc } 151*f4a2713aSLionel Sambuc 152*f4a2713aSLionel Sambuc namespace test2 { 153*f4a2713aSLionel Sambuc struct A { 154*f4a2713aSLionel Sambuc A(int); A(int, int); ~A(); 155*f4a2713aSLionel Sambuc void *p; 156*f4a2713aSLionel Sambuc void *operator new(size_t); 157*f4a2713aSLionel Sambuc void operator delete(void*, size_t); 158*f4a2713aSLionel Sambuc }; 159*f4a2713aSLionel Sambuc 160*f4a2713aSLionel Sambuc A *a() { 161*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test21aEv() 162*f4a2713aSLionel Sambuc // CHECK: [[NEW:%.*]] = call i8* @_ZN5test21AnwEm(i64 8) 163*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 164*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test21AC1Ei([[A]]* [[CAST]], i32 5) 165*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 166*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test21AdlEPvm(i8* [[NEW]], i64 8) 167*f4a2713aSLionel Sambuc // CHECK: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]] 168*f4a2713aSLionel Sambuc return new A(5); 169*f4a2713aSLionel Sambuc } 170*f4a2713aSLionel Sambuc } 171*f4a2713aSLionel Sambuc 172*f4a2713aSLionel Sambuc namespace test3 { 173*f4a2713aSLionel Sambuc struct A { 174*f4a2713aSLionel Sambuc A(int); A(int, int); A(const A&); ~A(); 175*f4a2713aSLionel Sambuc void *p; 176*f4a2713aSLionel Sambuc void *operator new(size_t, void*, double); 177*f4a2713aSLionel Sambuc void operator delete(void*, void*, double); 178*f4a2713aSLionel Sambuc }; 179*f4a2713aSLionel Sambuc 180*f4a2713aSLionel Sambuc void *foo(); 181*f4a2713aSLionel Sambuc double bar(); 182*f4a2713aSLionel Sambuc A makeA(), *makeAPtr(); 183*f4a2713aSLionel Sambuc 184*f4a2713aSLionel Sambuc A *a() { 185*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test31aEv() 186*f4a2713aSLionel Sambuc // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv() 187*f4a2713aSLionel Sambuc // CHECK: [[BAR:%.*]] = call double @_ZN5test33barEv() 188*f4a2713aSLionel Sambuc // CHECK: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[BAR]]) 189*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 190*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test31AC1Ei([[A]]* [[CAST]], i32 5) 191*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[CAST]] 192*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test31AdlEPvS1_d(i8* [[NEW]], i8* [[FOO]], double [[BAR]]) 193*f4a2713aSLionel Sambuc // CHECK: call void @__clang_call_terminate(i8* {{%.*}}) [[NR_NUW]] 194*f4a2713aSLionel Sambuc return new(foo(),bar()) A(5); 195*f4a2713aSLionel Sambuc } 196*f4a2713aSLionel Sambuc 197*f4a2713aSLionel Sambuc // rdar://problem/8439196 198*f4a2713aSLionel Sambuc A *b(bool cond) { 199*f4a2713aSLionel Sambuc 200*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test31bEb(i1 zeroext 201*f4a2713aSLionel Sambuc // CHECK: [[SAVED0:%.*]] = alloca i8* 202*f4a2713aSLionel Sambuc // CHECK-NEXT: [[SAVED1:%.*]] = alloca i8* 203*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 204*f4a2713aSLionel Sambuc 205*f4a2713aSLionel Sambuc // CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1 206*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]] 207*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[COND]] 208*f4a2713aSLionel Sambuc return (cond ? 209*f4a2713aSLionel Sambuc 210*f4a2713aSLionel Sambuc // CHECK: [[FOO:%.*]] = call i8* @_ZN5test33fooEv() 211*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test31AnwEmPvd(i64 8, i8* [[FOO]], double [[CONST:.*]]) 212*f4a2713aSLionel Sambuc // CHECK-NEXT: store i8* [[NEW]], i8** [[SAVED0]] 213*f4a2713aSLionel Sambuc // CHECK-NEXT: store i8* [[FOO]], i8** [[SAVED1]] 214*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[CLEANUPACTIVE]] 215*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 216*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test35makeAEv([[A]]* sret [[CAST]]) 217*f4a2713aSLionel Sambuc // CHECK: br label 218*f4a2713aSLionel Sambuc // -> cond.end 219*f4a2713aSLionel Sambuc new(foo(),10.0) A(makeA()) : 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel Sambuc // CHECK: [[MAKE:%.*]] = call [[A]]* @_ZN5test38makeAPtrEv() 222*f4a2713aSLionel Sambuc // CHECK: br label 223*f4a2713aSLionel Sambuc // -> cond.end 224*f4a2713aSLionel Sambuc makeAPtr()); 225*f4a2713aSLionel Sambuc 226*f4a2713aSLionel Sambuc // cond.end: 227*f4a2713aSLionel Sambuc // CHECK: [[RESULT:%.*]] = phi [[A]]* {{.*}}[[CAST]]{{.*}}[[MAKE]] 228*f4a2713aSLionel Sambuc // CHECK: ret [[A]]* [[RESULT]] 229*f4a2713aSLionel Sambuc 230*f4a2713aSLionel Sambuc // in the EH path: 231*f4a2713aSLionel Sambuc // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]] 232*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[ISACTIVE]] 233*f4a2713aSLionel Sambuc // CHECK: [[V0:%.*]] = load i8** [[SAVED0]] 234*f4a2713aSLionel Sambuc // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]] 235*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]]) 236*f4a2713aSLionel Sambuc } 237*f4a2713aSLionel Sambuc } 238*f4a2713aSLionel Sambuc 239*f4a2713aSLionel Sambuc namespace test4 { 240*f4a2713aSLionel Sambuc struct A { 241*f4a2713aSLionel Sambuc A(int); A(int, int); ~A(); 242*f4a2713aSLionel Sambuc void *p; 243*f4a2713aSLionel Sambuc void *operator new(size_t, void*, void*); 244*f4a2713aSLionel Sambuc void operator delete(void*, size_t, void*, void*); // not a match 245*f4a2713aSLionel Sambuc }; 246*f4a2713aSLionel Sambuc 247*f4a2713aSLionel Sambuc A *a() { 248*f4a2713aSLionel Sambuc // CHECK: define [[A:%.*]]* @_ZN5test41aEv() 249*f4a2713aSLionel Sambuc // CHECK: [[FOO:%.*]] = call i8* @_ZN5test43fooEv() 250*f4a2713aSLionel Sambuc // CHECK-NEXT: [[BAR:%.*]] = call i8* @_ZN5test43barEv() 251*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test41AnwEmPvS1_(i64 8, i8* [[FOO]], i8* [[BAR]]) 252*f4a2713aSLionel Sambuc // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* 253*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN5test41AC1Ei([[A]]* [[CAST]], i32 5) 254*f4a2713aSLionel Sambuc // CHECK-NEXT: ret [[A]]* [[CAST]] 255*f4a2713aSLionel Sambuc extern void *foo(), *bar(); 256*f4a2713aSLionel Sambuc 257*f4a2713aSLionel Sambuc return new(foo(),bar()) A(5); 258*f4a2713aSLionel Sambuc } 259*f4a2713aSLionel Sambuc } 260*f4a2713aSLionel Sambuc 261*f4a2713aSLionel Sambuc // PR7908 262*f4a2713aSLionel Sambuc namespace test5 { 263*f4a2713aSLionel Sambuc struct T { T(); ~T(); }; 264*f4a2713aSLionel Sambuc 265*f4a2713aSLionel Sambuc struct A { 266*f4a2713aSLionel Sambuc A(const A &x, const T &t = T()); 267*f4a2713aSLionel Sambuc ~A(); 268*f4a2713aSLionel Sambuc }; 269*f4a2713aSLionel Sambuc 270*f4a2713aSLionel Sambuc void foo(); 271*f4a2713aSLionel Sambuc 272*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test54testEv() 273*f4a2713aSLionel Sambuc // CHECK: [[EXNSLOT:%.*]] = alloca i8* 274*f4a2713aSLionel Sambuc // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 275*f4a2713aSLionel Sambuc // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1 276*f4a2713aSLionel Sambuc // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1 277*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test53fooEv() 278*f4a2713aSLionel Sambuc // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] 279*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) 280*f4a2713aSLionel Sambuc // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]* 281*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]]) 282*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]]) 283*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test51TD1Ev([[T_T]]* [[T]]) 284*f4a2713aSLionel Sambuc // CHECK: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]] 285*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A_T]]* [[A]]) 286*f4a2713aSLionel Sambuc // CHECK: call void @__cxa_end_catch() 287*f4a2713aSLionel Sambuc void test() { 288*f4a2713aSLionel Sambuc try { 289*f4a2713aSLionel Sambuc foo(); 290*f4a2713aSLionel Sambuc } catch (A a) { 291*f4a2713aSLionel Sambuc } 292*f4a2713aSLionel Sambuc } 293*f4a2713aSLionel Sambuc } 294*f4a2713aSLionel Sambuc 295*f4a2713aSLionel Sambuc // PR9303: invalid assert on this 296*f4a2713aSLionel Sambuc namespace test6 { 297*f4a2713aSLionel Sambuc bool cond(); 298*f4a2713aSLionel Sambuc void test() { 299*f4a2713aSLionel Sambuc try { 300*f4a2713aSLionel Sambuc lbl: 301*f4a2713aSLionel Sambuc if (cond()) goto lbl; 302*f4a2713aSLionel Sambuc } catch (...) { 303*f4a2713aSLionel Sambuc } 304*f4a2713aSLionel Sambuc } 305*f4a2713aSLionel Sambuc } 306*f4a2713aSLionel Sambuc 307*f4a2713aSLionel Sambuc // PR9298 308*f4a2713aSLionel Sambuc namespace test7 { 309*f4a2713aSLionel Sambuc struct A { A(); ~A(); }; 310*f4a2713aSLionel Sambuc struct B { 311*f4a2713aSLionel Sambuc // The throw() operator means that a bad allocation is signalled 312*f4a2713aSLionel Sambuc // with a null return, which means that the initializer is 313*f4a2713aSLionel Sambuc // evaluated conditionally. 314*f4a2713aSLionel Sambuc static void *operator new(size_t size) throw(); 315*f4a2713aSLionel Sambuc B(const A&, B*); 316*f4a2713aSLionel Sambuc ~B(); 317*f4a2713aSLionel Sambuc }; 318*f4a2713aSLionel Sambuc 319*f4a2713aSLionel Sambuc B *test() { 320*f4a2713aSLionel Sambuc // CHECK: define [[B:%.*]]* @_ZN5test74testEv() 321*f4a2713aSLionel Sambuc // CHECK: [[OUTER_NEW:%.*]] = alloca i1 322*f4a2713aSLionel Sambuc // CHECK-NEXT: alloca [[A:%.*]], 323*f4a2713aSLionel Sambuc // CHECK-NEXT: alloca i8* 324*f4a2713aSLionel Sambuc // CHECK-NEXT: alloca i32 325*f4a2713aSLionel Sambuc // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1 326*f4a2713aSLionel Sambuc // CHECK-NEXT: alloca i8* 327*f4a2713aSLionel Sambuc // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1 328*f4a2713aSLionel Sambuc // CHECK-NEXT: alloca [[A]] 329*f4a2713aSLionel Sambuc // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1 330*f4a2713aSLionel Sambuc 331*f4a2713aSLionel Sambuc // Allocate the outer object. 332*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( 333*f4a2713aSLionel Sambuc // CHECK-NEXT: icmp eq i8* [[NEW]], null 334*f4a2713aSLionel Sambuc 335*f4a2713aSLionel Sambuc // These stores, emitted before the outermost conditional branch, 336*f4a2713aSLionel Sambuc // deactivate the temporary cleanups. 337*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 false, i1* [[OUTER_NEW]] 338*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 false, i1* [[OUTER_A]] 339*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 false, i1* [[INNER_NEW]] 340*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 false, i1* [[INNER_A]] 341*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 342*f4a2713aSLionel Sambuc 343*f4a2713aSLionel Sambuc // We passed the first null check; activate that cleanup and continue. 344*f4a2713aSLionel Sambuc // CHECK: store i1 true, i1* [[OUTER_NEW]] 345*f4a2713aSLionel Sambuc // CHECK-NEXT: bitcast 346*f4a2713aSLionel Sambuc 347*f4a2713aSLionel Sambuc // Create the first A temporary and activate that cleanup. 348*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( 349*f4a2713aSLionel Sambuc // CHECK: store i1 true, i1* [[OUTER_A]] 350*f4a2713aSLionel Sambuc 351*f4a2713aSLionel Sambuc // Allocate the inner object. 352*f4a2713aSLionel Sambuc // CHECK-NEXT: [[NEW:%.*]] = call i8* @_ZN5test71BnwEm( 353*f4a2713aSLionel Sambuc // CHECK-NEXT: icmp eq i8* [[NEW]], null 354*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 355*f4a2713aSLionel Sambuc 356*f4a2713aSLionel Sambuc // We passed the second null check; save that pointer, activate 357*f4a2713aSLionel Sambuc // that cleanup, and continue. 358*f4a2713aSLionel Sambuc // CHECK: store i8* [[NEW]] 359*f4a2713aSLionel Sambuc // CHECK-NEXT: store i1 true, i1* [[INNER_NEW]] 360*f4a2713aSLionel Sambuc // CHECK-NEXT: bitcast 361*f4a2713aSLionel Sambuc 362*f4a2713aSLionel Sambuc // Build the second A temporary and activate that cleanup. 363*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test71AC1Ev( 364*f4a2713aSLionel Sambuc // CHECK: store i1 true, i1* [[INNER_A]] 365*f4a2713aSLionel Sambuc 366*f4a2713aSLionel Sambuc // Build the inner B object and deactivate the inner delete cleanup. 367*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( 368*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[INNER_NEW]] 369*f4a2713aSLionel Sambuc // CHECK: phi 370*f4a2713aSLionel Sambuc 371*f4a2713aSLionel Sambuc // Build the outer B object and deactivate the outer delete cleanup. 372*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN5test71BC1ERKNS_1AEPS0_( 373*f4a2713aSLionel Sambuc // CHECK: store i1 false, i1* [[OUTER_NEW]] 374*f4a2713aSLionel Sambuc // CHECK: phi 375*f4a2713aSLionel Sambuc // CHECK-NEXT: store [[B]]* 376*f4a2713aSLionel Sambuc 377*f4a2713aSLionel Sambuc // Destroy the inner A object. 378*f4a2713aSLionel Sambuc // CHECK-NEXT: load i1* [[INNER_A]] 379*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 380*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test71AD1Ev( 381*f4a2713aSLionel Sambuc 382*f4a2713aSLionel Sambuc // Destroy the outer A object. 383*f4a2713aSLionel Sambuc // CHECK: load i1* [[OUTER_A]] 384*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 385*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN5test71AD1Ev( 386*f4a2713aSLionel Sambuc 387*f4a2713aSLionel Sambuc return new B(A(), new B(A(), 0)); 388*f4a2713aSLionel Sambuc } 389*f4a2713aSLionel Sambuc } 390*f4a2713aSLionel Sambuc 391*f4a2713aSLionel Sambuc // Just don't crash. 392*f4a2713aSLionel Sambuc namespace test8 { 393*f4a2713aSLionel Sambuc struct A { 394*f4a2713aSLionel Sambuc // Having both of these is required to trigger the assert we're 395*f4a2713aSLionel Sambuc // trying to avoid. 396*f4a2713aSLionel Sambuc A(const A&); 397*f4a2713aSLionel Sambuc A&operator=(const A&); 398*f4a2713aSLionel Sambuc 399*f4a2713aSLionel Sambuc ~A(); 400*f4a2713aSLionel Sambuc }; 401*f4a2713aSLionel Sambuc 402*f4a2713aSLionel Sambuc A makeA(); 403*f4a2713aSLionel Sambuc void test() { 404*f4a2713aSLionel Sambuc throw makeA(); 405*f4a2713aSLionel Sambuc } 406*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test84testEv 407*f4a2713aSLionel Sambuc } 408*f4a2713aSLionel Sambuc 409*f4a2713aSLionel Sambuc // Make sure we generate the correct code for the delete[] call which 410*f4a2713aSLionel Sambuc // happens if A::A() throws. (We were previously calling delete[] on 411*f4a2713aSLionel Sambuc // a pointer to the first array element, not the pointer returned by new[].) 412*f4a2713aSLionel Sambuc // PR10870 413*f4a2713aSLionel Sambuc namespace test9 { 414*f4a2713aSLionel Sambuc struct A { 415*f4a2713aSLionel Sambuc A(); 416*f4a2713aSLionel Sambuc ~A(); 417*f4a2713aSLionel Sambuc }; 418*f4a2713aSLionel Sambuc A* test() { 419*f4a2713aSLionel Sambuc return new A[10]; 420*f4a2713aSLionel Sambuc } 421*f4a2713aSLionel Sambuc // CHECK: define {{%.*}}* @_ZN5test94testEv 422*f4a2713aSLionel Sambuc // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam 423*f4a2713aSLionel Sambuc // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) 424*f4a2713aSLionel Sambuc } 425*f4a2713aSLionel Sambuc 426*f4a2713aSLionel Sambuc // In a destructor with a function-try-block, a return statement in a 427*f4a2713aSLionel Sambuc // catch handler behaves differently from running off the end of the 428*f4a2713aSLionel Sambuc // catch handler. PR13102. 429*f4a2713aSLionel Sambuc namespace test10 { 430*f4a2713aSLionel Sambuc extern void cleanup(); 431*f4a2713aSLionel Sambuc extern bool suppress; 432*f4a2713aSLionel Sambuc 433*f4a2713aSLionel Sambuc struct A { ~A(); }; 434*f4a2713aSLionel Sambuc A::~A() try { cleanup(); } catch (...) { return; } 435*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test101AD1Ev( 436*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN6test107cleanupEv() 437*f4a2713aSLionel Sambuc // CHECK-NOT: rethrow 438*f4a2713aSLionel Sambuc // CHECK: ret void 439*f4a2713aSLionel Sambuc 440*f4a2713aSLionel Sambuc struct B { ~B(); }; 441*f4a2713aSLionel Sambuc B::~B() try { cleanup(); } catch (...) {} 442*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test101BD1Ev( 443*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN6test107cleanupEv() 444*f4a2713aSLionel Sambuc // CHECK: call i8* @__cxa_begin_catch 445*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @__cxa_rethrow() 446*f4a2713aSLionel Sambuc // CHECK: unreachable 447*f4a2713aSLionel Sambuc 448*f4a2713aSLionel Sambuc struct C { ~C(); }; 449*f4a2713aSLionel Sambuc C::~C() try { cleanup(); } catch (...) { if (suppress) return; } 450*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test101CD1Ev( 451*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN6test107cleanupEv() 452*f4a2713aSLionel Sambuc // CHECK: call i8* @__cxa_begin_catch 453*f4a2713aSLionel Sambuc // CHECK-NEXT: load i8* @_ZN6test108suppressE, align 1 454*f4a2713aSLionel Sambuc // CHECK-NEXT: trunc 455*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 456*f4a2713aSLionel Sambuc // CHECK: call void @__cxa_end_catch() 457*f4a2713aSLionel Sambuc // CHECK-NEXT: br label 458*f4a2713aSLionel Sambuc // CHECK: invoke void @__cxa_rethrow() 459*f4a2713aSLionel Sambuc // CHECK: unreachable 460*f4a2713aSLionel Sambuc } 461*f4a2713aSLionel Sambuc 462*f4a2713aSLionel Sambuc // Ensure that an exception in a constructor destroys 463*f4a2713aSLionel Sambuc // already-constructed array members. PR14514 464*f4a2713aSLionel Sambuc namespace test11 { 465*f4a2713aSLionel Sambuc struct A { 466*f4a2713aSLionel Sambuc A(); 467*f4a2713aSLionel Sambuc ~A() {} 468*f4a2713aSLionel Sambuc }; 469*f4a2713aSLionel Sambuc 470*f4a2713aSLionel Sambuc struct C { 471*f4a2713aSLionel Sambuc A single; 472*f4a2713aSLionel Sambuc A array[2][3]; 473*f4a2713aSLionel Sambuc 474*f4a2713aSLionel Sambuc C(); 475*f4a2713aSLionel Sambuc }; 476*f4a2713aSLionel Sambuc 477*f4a2713aSLionel Sambuc C::C() { 478*f4a2713aSLionel Sambuc throw 0; 479*f4a2713aSLionel Sambuc } 480*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN6test111CC2Ev( 481*f4a2713aSLionel Sambuc // CHECK: [[THIS:%.*]] = load [[C:%.*]]** {{%.*}} 482*f4a2713aSLionel Sambuc // Construct single. 483*f4a2713aSLionel Sambuc // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 0 484*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]]) 485*f4a2713aSLionel Sambuc // Construct array. 486*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 1 487*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 488*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6 489*f4a2713aSLionel Sambuc // CHECK-NEXT: br label 490*f4a2713aSLionel Sambuc // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] 491*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]]) 492*f4a2713aSLionel Sambuc // CHECK: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 493*f4a2713aSLionel Sambuc // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]] 494*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[DONE]], 495*f4a2713aSLionel Sambuc // throw 0; 496*f4a2713aSLionel Sambuc // CHECK: invoke void @__cxa_throw( 497*f4a2713aSLionel Sambuc // Landing pad 1, from constructor in array-initialization loop: 498*f4a2713aSLionel Sambuc // CHECK: landingpad 499*f4a2713aSLionel Sambuc // - First, destroy already-constructed bits of array. 500*f4a2713aSLionel Sambuc // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]] 501*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[EMPTY]] 502*f4a2713aSLionel Sambuc // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] 503*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 504*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]]) 505*f4a2713aSLionel Sambuc // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]] 506*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[DONE]], 507*f4a2713aSLionel Sambuc // - Next, chain to cleanup for single. 508*f4a2713aSLionel Sambuc // CHECK: br label 509*f4a2713aSLionel Sambuc // Landing pad 2, from throw site. 510*f4a2713aSLionel Sambuc // CHECK: landingpad 511*f4a2713aSLionel Sambuc // - First, destroy all of array. 512*f4a2713aSLionel Sambuc // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 513*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6 514*f4a2713aSLionel Sambuc // CHECK-NEXT: br label 515*f4a2713aSLionel Sambuc // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] 516*f4a2713aSLionel Sambuc // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 517*f4a2713aSLionel Sambuc // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]]) 518*f4a2713aSLionel Sambuc // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]] 519*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[DONE]], 520*f4a2713aSLionel Sambuc // - Next, chain to cleanup for single. 521*f4a2713aSLionel Sambuc // CHECK: br label 522*f4a2713aSLionel Sambuc // Finally, the cleanup for single. 523*f4a2713aSLionel Sambuc // CHECK: invoke void @_ZN6test111AD1Ev([[A]]* [[SINGLE]]) 524*f4a2713aSLionel Sambuc // CHECK: br label 525*f4a2713aSLionel Sambuc // CHECK: resume 526*f4a2713aSLionel Sambuc // (After this is a terminate landingpad.) 527*f4a2713aSLionel Sambuc } 528*f4a2713aSLionel Sambuc 529*f4a2713aSLionel Sambuc // CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind } 530