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