brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.8 KiB · 61cffd1 Raw
626 lines · cpp
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 %s2// 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 %s3// 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 %s4 5// CHECK: %[[STRUCT_TEST13_A:.*]] = type { i32, i32 }6 7typedef __typeof(sizeof(0)) size_t;8 9// Declare the reserved global placement new.10void *operator new(size_t, void*);11 12// This just shouldn't crash.13namespace test0 {14  struct allocator {15    allocator();16    allocator(const allocator&);17    ~allocator();18  };19 20  void f();21  void g(bool b, bool c) {22    if (b) {23      if (!c)24        throw allocator();25 26      return;27    }28    f();29  }30}31 32namespace test1 {33  struct A { A(int); A(int, int); ~A(); void *p; };34 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);42  }43 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());53  }54 55  struct B { B(); ~B(); operator int(); int x; };56  B makeB();57 58  A *c() {59    // CHECK:    define{{( dso_local)?}} ptr @_ZN5test11cEv()60    // CHECK:      [[ACTIVE:%.*]] = alloca i161    // 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 065    // CHECK-NEXT: [[T2:%.*]] = load i32, ptr [[T1]], align 466    // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T2]])67    // CHECK:      store i1 false, ptr [[ACTIVE]]68 69    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])70    // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])71 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);77  }78 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]+]] comdat81  // 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:   unreachable84 85  A *d() {86    // CHECK:    define{{( dso_local)?}} ptr @_ZN5test11dEv()87    // CHECK:      [[ACTIVE:%.*]] = alloca i188    // 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]]94 95    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])96    // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])97 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());103  }104 105  A *e() {106    // CHECK:    define{{( dso_local)?}} ptr @_ZN5test11eEv()107    // CHECK:      [[ACTIVE:%.*]] = alloca i1108    // 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]]116 117    // CHECK98-NEXT: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])118    // CHECK11-NEXT: call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])119 120    // CHECK98:      invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])121    // CHECK11:      call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])122 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());128  }129  A *f() {130    return new A(makeB().x);131  }132  A *g() {133    return new A(makeB());134  }135  A *h() {136    return new A(makeB(), makeB());137  }138 139  A *i() {140    // CHECK:    define{{( dso_local)?}} ptr @_ZN5test11iEv()141    // CHECK:      [[X:%.*]] = alloca ptr, align 8142    // CHECK:      [[ACTIVE:%.*]] = alloca i1143    // 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 8150    // CHECK:      invoke void @_ZN5test15makeBEv(ptr dead_on_unwind writable sret([[B:%.*]]) align 4 [[T2:%.*]])151    // CHECK:      [[RET:%.*]] = load ptr, ptr [[X]], align 8152 153    // CHECK98:      invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])154    // CHECK11:      call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]])155 156    // CHECK98:      invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])157    // CHECK11:      call void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T0]])158 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);165  }166}167 168namespace 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);174  };175 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]]181 182    // CHECK98:      invoke void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)183    // CHECK11:      call void @_ZN5test21AdlEPvm(ptr [[NEW]], i64 8)184 185    // CHECK98:      call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]186    return new A(5);187  }188}189 190namespace 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);196  };197 198  void *foo();199  double bar();200  A makeA(), *makeAPtr();201 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]]209 210    // CHECK98:      invoke void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])211    // CHECK11:      call void @_ZN5test31AdlEPvS1_d(ptr [[NEW]], ptr [[FOO]], double [[BAR]])212 213    // CHECK98:      call void @__clang_call_terminate(ptr {{%.*}}) [[NR_NUW]]214    return new(foo(),bar()) A(5);215  }216 217  A *b(bool cond) {218 219    // CHECK:    define{{( dso_local)?}} ptr @_ZN5test31bEb(i1 zeroext220    // CHECK:      [[SAVED0:%.*]] = alloca ptr221    // CHECK-NEXT: [[SAVED1:%.*]] = alloca ptr222    // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1223 224    // CHECK:      [[COND:%.*]] = trunc i8 {{.*}} to i1225    // CHECK-NEXT: store i1 false, ptr [[CLEANUPACTIVE]]226    // CHECK-NEXT: br i1 [[COND]]227    return (cond ?228 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 label236    //   -> cond.end237            new(foo(),10.0) A(makeA()) :238 239    // CHECK:      [[MAKE:%.*]] = call ptr @_ZN5test38makeAPtrEv()240    // CHECK:      br label241    //   -> cond.end242            makeAPtr());243 244    // cond.end:245    // CHECK:      [[RESULT:%.*]] = phi ptr {{.*}}[[NEW]]{{.*}}[[MAKE]]246    // CHECK:      ret ptr [[RESULT]]247 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]]253 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]])256  }257}258 259namespace 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 match265  };266 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();275 276    return new(foo(),bar()) A(5);277  }278}279 280// PR7908281namespace test5 {282  struct T { T(); ~T(); };283 284  struct A {285    A(const A &x, const T &t = T());286    ~A();287  };288 289  void foo();290 291  // CHECK-LABEL:    define{{.*}} void @_ZN5test54testEv()292  // CHECK:      [[EXNSLOT:%.*]] = alloca ptr293  // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32294  // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1295  // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1296  // 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]])301 302  // CHECK98:      invoke void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])303  // CHECK11:      call void @_ZN5test51TD1Ev(ptr {{[^,]*}} [[T]])304 305  // CHECK98:      call ptr @__cxa_begin_catch(ptr [[EXN]]) [[NUW]]306  // CHECK98-NEXT: invoke void @_ZN5test51AD1Ev(ptr {{[^,]*}} [[A:%.*]])307 308  // CHECK:      call void @__cxa_end_catch()309  void test() {310    try {311      foo();312    } catch (A a) {313    }314  }315}316 317// PR9303: invalid assert on this318namespace test6 {319  bool cond();320  void test() {321    try {322    lbl:323      if (cond()) goto lbl;324    } catch (...) {325    }326  }327}328 329// PR9298330namespace test7 {331  struct A { A(); ~A(); };332  struct B {333    // The throw() operator means that a bad allocation is signalled334    // with a null return, which means that the initializer is335    // evaluated conditionally.336    static void *operator new(size_t size) throw();337    B(const A&, B*);338    ~B();339  };340 341  B *test() {342    // CHECK: define{{( dso_local)?}} ptr @_ZN5test74testEv()343    // CHECK:      [[OUTER_NEW:%.*]] = alloca i1344    // CHECK-NEXT: alloca [[A:%.*]],345    // CHECK-NEXT: alloca ptr346    // CHECK-NEXT: alloca i32347    // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1348    // CHECK-NEXT: alloca ptr349    // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1350    // CHECK-NEXT: alloca [[A:%.*]]351    // CHECK-NEXT: [[INNER_A:%.*]] = alloca i1352 353    // Allocate the outer object.354    // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(355    // CHECK-NEXT: icmp eq ptr [[NEW]], null356 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 i1364 365    // We passed the first null check; activate that cleanup and continue.366    // CHECK:      store i1 true, ptr [[OUTER_NEW]]367 368    // Create the first A temporary and activate that cleanup.369    // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(370    // CHECK:      store i1 true, ptr [[OUTER_A]]371 372    // Allocate the inner object.373    // CHECK-NEXT: [[NEW:%.*]] = call ptr @_ZN5test71BnwEm(374    // CHECK-NEXT: icmp eq ptr [[NEW]], null375    // CHECK-NEXT: br i1376 377    // We passed the second null check; save that pointer, activate378    // that cleanup, and continue.379    // CHECK:      store ptr [[NEW]]380    // CHECK-NEXT: store i1 true, ptr [[INNER_NEW]]381 382    // Build the second A temporary and activate that cleanup.383    // CHECK-NEXT: invoke void @_ZN5test71AC1Ev(384    // CHECK:      store i1 true, ptr [[INNER_A]]385 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:      phi390 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:      phi395    // CHECK-NEXT: store ptr396 397    // Destroy the inner A object.398    // CHECK-NEXT: load i1, ptr [[INNER_A]]399    // CHECK-NEXT: br i1400 401    // CHECK98:    invoke void @_ZN5test71AD1Ev(402    // CHECK11:    call void @_ZN5test71AD1Ev(403 404    // Destroy the outer A object.405    // CHECK:      load i1, ptr [[OUTER_A]]406    // CHECK-NEXT: br i1407 408    // CHECK98:    invoke void @_ZN5test71AD1Ev(409    // CHECK11:    call void @_ZN5test71AD1Ev(410 411    return new B(A(), new B(A(), 0));412  }413}414 415// Just don't crash.416namespace test8 {417  struct A {418    // Having both of these is required to trigger the assert we're419    // trying to avoid.420    A(const A&);421    A&operator=(const A&);422 423    ~A();424  };425 426  A makeA();427  void test() {428    throw makeA();429  }430  // CHECK-LABEL: define{{.*}} void @_ZN5test84testEv431}432 433// Make sure we generate the correct code for the delete[] call which434// happens if A::A() throws.  (We were previously calling delete[] on435// a pointer to the first array element, not the pointer returned by new[].)436// PR10870437namespace test9 {438  struct A {439    A();440    ~A();441  };442  A* test() {443    return new A[10];444  }445  // CHECK: define{{.*}} ptr @_ZN5test94testEv446  // CHECK: [[TEST9_NEW:%.*]] = call noalias nonnull ptr @_Znam447  // CHECK: call void @_ZdaPv(ptr [[TEST9_NEW]])448}449 450// In a destructor with a function-try-block, a return statement in a451// catch handler behaves differently from running off the end of the452// catch handler.  PR13102.453namespace test10 {454  extern void cleanup();455  extern bool suppress;456 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:  rethrow462  // CHECK:      ret void463 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_catch469  // CHECK-NEXT: invoke void @__cxa_rethrow()470  // CHECK:      unreachable471 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_catch477  // CHECK-NEXT: load i8, ptr @_ZN6test108suppressE, align 1478  // CHECK-NEXT: trunc479  // CHECK-NEXT: br i1480 481  // CHECK98:      call void @__cxa_end_catch()482  // CHECK98-NEXT: br label483  // THROWEND11:        invoke void @__cxa_end_catch()484  // THROWEND11-NEXT:   to label %invoke.cont[[#]] unwind label %terminate.lpad485  // NOTHROWEND11:      call void @__cxa_end_catch()486  // NOTHROWEND11-NEXT: br label %try.cont487 488  // CHECK:      invoke void @__cxa_rethrow()489  // CHECK:      unreachable490 491  // CHECK:      terminate.lpad:492  // CHECK:        call void @__clang_call_terminate(493}494 495// Ensure that an exception in a constructor destroys496// already-constructed array members.  PR14514497namespace test11 {498  struct A {499    A();500    ~A() {}501  };502 503  struct C {504    A single;505    A array[2][3];506 507    C();508  };509 510  C::C() {511    throw 0;512  }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 1519  // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0520  // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6521  // CHECK-NEXT: br label522  // CHECK:      [[CUR:%.*]] = phi ptr [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]523  // CHECK-NEXT: invoke void @_ZN6test111AC1Ev(ptr {{[^,]*}} [[CUR]])524  // CHECK:      [[NEXT]] = getelementptr inbounds [[A:%.*]], ptr [[CUR]], i64 1525  // 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:      landingpad531  //     - 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 -1536 537  // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])538  // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])539 540  // CHECK:      [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]541  // CHECK-NEXT: br i1 [[DONE]],542  //     - Next, chain to cleanup for single.543  // CHECK:      br label544  //   Landing pad 2, from throw site.545  // CHECK:      landingpad546  //     - First, destroy all of array.547  // CHECK:      [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A:%.*]]]], ptr [[ARRAY]], i32 0, i32 0, i32 0548  // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A:%.*]], ptr [[ARRAYBEGIN]], i64 6549  // CHECK-NEXT: br label550  // CHECK:      [[AFTER:%.*]] = phi ptr [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]551  // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], ptr [[AFTER]], i64 -1552 553  // CHECK98-NEXT: invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])554  // CHECK11-NEXT: call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[ELT]])555 556  // CHECK:      [[DONE:%.*]] = icmp eq ptr [[ELT]], [[ARRAYBEGIN]]557  // CHECK-NEXT: br i1 [[DONE]],558  //     - Next, chain to cleanup for single.559  // CHECK:      br label560  //   Finally, the cleanup for single.561 562  // CHECK98:      invoke void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])563  // CHECK11:      call void @_ZN6test111AD1Ev(ptr {{[^,]*}} [[THIS]])564 565  // CHECK:      br label566  // CHECK:      resume567  //   (After this is a terminate landingpad.)568}569 570namespace test12 {571  struct A {572    void operator delete(void *, void *);573    A();574  };575 576  A *test(void *ptr) {577    return new (ptr) A();578  }579  // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv(580  // CHECK:       [[PTR:%.*]] = load ptr, ptr581  // CHECK-NEXT:  invoke void @_ZN6test121AC1Ev(ptr {{[^,]*}} [[PTR]])582  // CHECK:       ret ptr [[PTR]]583 584  // CHECK98:       invoke void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])585  // CHECK11:       call void @_ZN6test121AdlEPvS1_(ptr [[PTR]], ptr [[PTR]])586}587 588namespace test13 {589 590struct A {591  A();592  ~A();593  int a, b;594};595 596// CHECK: define{{.*}} void @_ZN6test134testEi(597// CHECK: %[[REF_TMP:.*]] = alloca %[[STRUCT_TEST13_A]], align 4598// CHECK: %[[CLEANUP_COND:.*]] = alloca i1, align 1599// CHECK: %[[REF_TMP1:.*]] = alloca %[[STRUCT_TEST13_A]], align 4600// CHECK: %[[CLEANUP_COND2:.*]] = alloca i1, align 1601 602// CHECK: call void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP]])603// CHECK: store i1 true, ptr %[[CLEANUP_COND]], align 1604// CHECK: br605 606// CHECK: invoke void @_ZN6test131AC1Ev(ptr {{[^,]*}} %[[REF_TMP1]])607 608// CHECK: store i1 true, ptr %[[CLEANUP_COND2]], align 1609// CHECK: br610 611// Check the flag before destructing the temporary.612 613// CHECK: landingpad { ptr, i32 }614// CHECK: %[[CLEANUP_IS_ACTIVE:.*]] = load i1, ptr %[[CLEANUP_COND]], align 1615// CHECK: br i1 %[[CLEANUP_IS_ACTIVE]],616 617// CHECK: void @_ZN6test131AD1Ev(ptr {{[^,]*}} %[[REF_TMP]])618 619void test(int c) {620  const A &s = c ? static_cast<const A &>(A()) : static_cast<const A &>(A());621}622 623}624 625// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind {{.*}} }626