Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - -mconstructor-aliases -fcxx-exceptions -fexceptions -O1 -disable-llvm-optzns | FileCheck %s
      2 
      3 // CHECK-DAG: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
      4 // CHECK-DAG: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
      5 // CHECK-DAG: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
      6 // CHECK-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
      7 // CHECK-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
      8 
      9 // WIN32-DAG: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
     10 // WIN32-DAG: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
     11 // WIN32-DAG: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
     12 // WIN32-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
     13 // WIN32-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
     14 
     15 
     16 struct A {
     17   int a;
     18 
     19   ~A();
     20 };
     21 
     22 // Base with non-trivial destructor
     23 struct B : A {
     24   ~B();
     25 };
     26 
     27 B::~B() { }
     28 
     29 // Field with non-trivial destructor
     30 struct C {
     31   A a;
     32 
     33   ~C();
     34 };
     35 
     36 C::~C() { }
     37 
     38 namespace PR7526 {
     39   extern void foo();
     40   struct allocator {
     41     ~allocator() throw();
     42   };
     43 
     44   struct allocator_derived : allocator { };
     45 
     46   // CHECK-LABEL: define void @_ZN6PR75263fooEv()
     47   // CHECK: call void {{.*}} @_ZN6PR75269allocatorD2Ev
     48 
     49   // CHECK-LABEL: define void @_ZN6PR75269allocatorD2Ev(%"struct.PR7526::allocator"* %this) unnamed_addr
     50   // CHECK: call void @__cxa_call_unexpected
     51   allocator::~allocator() throw() { foo(); }
     52 
     53   void foo() {
     54     allocator_derived ad;
     55   }
     56 }
     57 
     58 // PR5084
     59 template<typename T>
     60 class A1 {
     61   ~A1();
     62 };
     63 
     64 template<> A1<char>::~A1();
     65 
     66 // PR5529
     67 namespace PR5529 {
     68   struct A {
     69     ~A();
     70   };
     71 
     72   A::~A() { }
     73   struct B : A {
     74     virtual ~B();
     75   };
     76 
     77   B::~B()  {}
     78 }
     79 
     80 // FIXME: there's a known problem in the codegen here where, if one
     81 // destructor throws, the remaining destructors aren't run.  Fix it,
     82 // then make this code check for it.
     83 namespace test0 {
     84   void foo();
     85   struct VBase { ~VBase(); };
     86   struct Base { ~Base(); };
     87   struct Member { ~Member(); };
     88 
     89   struct A : Base {
     90     Member M;
     91     ~A();
     92   };
     93 
     94   // The function-try-block won't suppress -mconstructor-aliases here.
     95   A::~A() try { } catch (int i) {}
     96 
     97 // complete destructor alias tested above
     98 
     99 // CHECK-LABEL: define void @_ZN5test01AD2Ev(%"struct.test0::A"* %this) unnamed_addr
    100 // CHECK: invoke void @_ZN5test06MemberD1Ev
    101 // CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
    102 // CHECK: invoke void @_ZN5test04BaseD2Ev
    103 // CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
    104 
    105   struct B : Base, virtual VBase {
    106     Member M;
    107     ~B();
    108   };
    109   B::~B() try { } catch (int i) {}
    110   // It will suppress the delegation optimization here, though.
    111 
    112 // CHECK-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
    113 // CHECK: invoke void @_ZN5test06MemberD1Ev
    114 // CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
    115 // CHECK: invoke void @_ZN5test04BaseD2Ev
    116 // CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
    117 
    118 // CHECK-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
    119 // CHECK: invoke void @_ZN5test06MemberD1Ev
    120 // CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
    121 // CHECK: invoke void @_ZN5test04BaseD2Ev
    122 // CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
    123 // CHECK: invoke void @_ZN5test05VBaseD2Ev
    124 // CHECK:   unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
    125 }
    126 
    127 // Test base-class aliasing.
    128 namespace test1 {
    129   struct A { ~A(); char ***m; }; // non-trivial destructor
    130   struct B { ~B(); }; // non-trivial destructor
    131   struct Empty { }; // trivial destructor, empty
    132   struct NonEmpty { int x; }; // trivial destructor, non-empty
    133 
    134   // There must be a definition in this translation unit for the alias
    135   // optimization to apply.
    136   A::~A() { delete m; }
    137 
    138   struct M : A { ~M(); };
    139   M::~M() {} // alias tested above
    140 
    141   struct N : A, Empty { ~N(); };
    142   N::~N() {} // alias tested above
    143 
    144   struct O : Empty, A { ~O(); };
    145   O::~O() {} // alias tested above
    146 
    147   struct P : NonEmpty, A { ~P(); };
    148   P::~P() {} // CHECK-LABEL: define void @_ZN5test11PD2Ev(%"struct.test1::P"* %this) unnamed_addr
    149 
    150   struct Q : A, B { ~Q(); };
    151   Q::~Q() {} // CHECK-LABEL: define void @_ZN5test11QD2Ev(%"struct.test1::Q"* %this) unnamed_addr
    152 
    153   struct R : A { ~R(); };
    154   R::~R() { A a; } // CHECK-LABEL: define void @_ZN5test11RD2Ev(%"struct.test1::R"* %this) unnamed_addr
    155 
    156   struct S : A { ~S(); int x; };
    157   S::~S() {} // alias tested above
    158 
    159   struct T : A { ~T(); B x; };
    160   T::~T() {} // CHECK-LABEL: define void @_ZN5test11TD2Ev(%"struct.test1::T"* %this) unnamed_addr
    161 
    162   // The VTT parameter prevents this.  We could still make this work
    163   // for calling conventions that are safe against extra parameters.
    164   struct U : A, virtual B { ~U(); };
    165   U::~U() {} // CHECK-LABEL: define void @_ZN5test11UD2Ev(%"struct.test1::U"* %this, i8** %vtt) unnamed_addr
    166 }
    167 
    168 // PR6471
    169 namespace test2 {
    170   struct A { ~A(); char ***m; };
    171   struct B : A { ~B(); };
    172 
    173   B::~B() {}
    174   // CHECK-LABEL: define void @_ZN5test21BD2Ev(%"struct.test2::B"* %this) unnamed_addr
    175   // CHECK: call void @_ZN5test21AD2Ev
    176 }
    177 
    178 // PR7142
    179 namespace test3 {
    180   struct A { virtual ~A(); };
    181   struct B { virtual ~B(); };
    182   namespace { // internal linkage => deferred
    183     struct C : A, B {}; // ~B() in D requires a this-adjustment thunk
    184     struct D : C {};    // D::~D() is an alias to C::~C()
    185   }
    186 
    187   void test() {
    188     new D; // Force emission of D's vtable
    189   }
    190 }
    191 
    192 namespace test4 {
    193   struct A { ~A(); };
    194 
    195   // CHECK-LABEL: define void @_ZN5test43fooEv()
    196   // CHECK: call void @_ZN5test41AD1Ev
    197   // CHECK: ret void
    198   void foo() {
    199     {
    200       A a;
    201       goto failure;
    202     }
    203 
    204   failure:
    205     return;
    206   }
    207 
    208   // CHECK-LABEL: define void @_ZN5test43barEi(
    209   // CHECK:      [[X:%.*]] = alloca i32
    210   // CHECK-NEXT: [[A:%.*]] = alloca
    211   // CHECK:      br label
    212   // CHECK:      [[TMP:%.*]] = load i32* [[X]]
    213   // CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0
    214   // CHECK-NEXT: br i1
    215   // CHECK:      call void @_ZN5test41AD1Ev(
    216   // CHECK:      br label
    217   // CHECK:      [[TMP:%.*]] = load i32* [[X]]
    218   // CHECK:      [[TMP2:%.*]] = add nsw i32 [[TMP]], -1
    219   // CHECK:      store i32 [[TMP2]], i32* [[X]]
    220   // CHECK:      br label
    221   // CHECK:      ret void
    222   void bar(int x) {
    223     for (A a; x; ) {
    224       x--;
    225     }
    226   }
    227 }
    228 
    229 // PR7575
    230 namespace test5 {
    231   struct A { ~A(); };
    232 
    233   // CHECK-LABEL: define void @_ZN5test53fooEv()
    234   // CHECK:      [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
    235   // CHECK-NEXT: [[EXN:%.*]] = alloca i8*
    236   // CHECK-NEXT: [[SEL:%.*]] = alloca i32
    237   // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
    238   // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5
    239   // CHECK-NEXT: br label
    240   // CHECK:      [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
    241   // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1
    242   // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])
    243   // CHECK:      [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
    244   // CHECK-NEXT: br i1 [[T0]],
    245   // CHECK:      ret void
    246   // lpad
    247   // CHECK:      [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]
    248   // CHECK-NEXT: br i1 [[EMPTY]]
    249   // CHECK:      [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
    250   // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
    251   // CHECK-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]])
    252   // CHECK:      [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
    253   // CHECK-NEXT: br i1 [[DONE]],
    254   void foo() {
    255     A elems[5];
    256   }
    257 }
    258 
    259 namespace test6 {
    260   void opaque();
    261 
    262   struct A { ~A(); };
    263   template <unsigned> struct B { B(); ~B(); int _; };
    264   struct C : B<0>, B<1>, virtual B<2>, virtual B<3> {
    265     A x, y, z;
    266 
    267     C();
    268     ~C();
    269   };
    270 
    271   C::C() { opaque(); }
    272   // CHECK-LABEL: define void @_ZN5test61CC1Ev(%"struct.test6::C"* %this) unnamed_addr
    273   // CHECK:   call void @_ZN5test61BILj2EEC2Ev
    274   // CHECK:   invoke void @_ZN5test61BILj3EEC2Ev
    275   // CHECK:   invoke void @_ZN5test61BILj0EEC2Ev
    276   // CHECK:   invoke void @_ZN5test61BILj1EEC2Ev
    277   // CHECK:   invoke void @_ZN5test66opaqueEv
    278   // CHECK:   ret void
    279   // FIXME: way too much EH cleanup code follows
    280 
    281   C::~C() { opaque(); }
    282   // CHECK-LABEL: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
    283   // CHECK:   invoke void @_ZN5test66opaqueEv
    284   // CHECK:   invoke void @_ZN5test61AD1Ev
    285   // CHECK:   invoke void @_ZN5test61AD1Ev
    286   // CHECK:   invoke void @_ZN5test61AD1Ev
    287   // CHECK:   invoke void @_ZN5test61BILj1EED2Ev
    288   // CHECK:   call void @_ZN5test61BILj0EED2Ev
    289   // CHECK:   ret void
    290   // CHECK:   invoke void @_ZN5test61AD1Ev
    291   // CHECK:   invoke void @_ZN5test61AD1Ev
    292   // CHECK:   invoke void @_ZN5test61AD1Ev
    293   // CHECK:   invoke void @_ZN5test61BILj1EED2Ev
    294   // CHECK:   invoke void @_ZN5test61BILj0EED2Ev
    295 
    296   // CHECK-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
    297   // CHECK:   invoke void @_ZN5test61CD2Ev
    298   // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
    299   // CHECK:   call void @_ZN5test61BILj2EED2Ev
    300   // CHECK:   ret void
    301   // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
    302   // CHECK:   invoke void @_ZN5test61BILj2EED2Ev
    303 }
    304 
    305 // PR 9197
    306 namespace test7 {
    307   struct D { ~D(); };
    308 
    309   struct A { ~A(); };
    310   A::~A() { }
    311 
    312   struct B : public A {
    313     ~B();
    314     D arr[1];
    315   };
    316 
    317   // Verify that this doesn't get emitted as an alias
    318   // CHECK-LABEL: define void @_ZN5test71BD2Ev(
    319   // CHECK:   invoke void @_ZN5test71DD1Ev(
    320   // CHECK:   call void @_ZN5test71AD2Ev(
    321   B::~B() {}
    322 }
    323 
    324 // PR10467
    325 namespace test8 {
    326   struct A { A(); ~A(); };
    327 
    328   void die() __attribute__((noreturn));
    329   void test() {
    330     A x;
    331     while (1) {
    332       A y;
    333       goto l;
    334     }
    335   l: die();
    336   }
    337 
    338   // CHECK-LABEL:    define void @_ZN5test84testEv()
    339   // CHECK:      [[X:%.*]] = alloca [[A:%.*]], align 1
    340   // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]], align 1
    341   // CHECK:      call void @_ZN5test81AC1Ev([[A]]* [[X]])
    342   // CHECK-NEXT: br label
    343   // CHECK:      invoke void @_ZN5test81AC1Ev([[A]]* [[Y]])
    344   // CHECK:      invoke void @_ZN5test81AD1Ev([[A]]* [[Y]])
    345   // CHECK-NOT:  switch
    346   // CHECK:      invoke void @_ZN5test83dieEv()
    347   // CHECK:      unreachable
    348 }
    349 
    350 // PR12710
    351 namespace test9 {
    352   struct ArgType {
    353     ~ArgType();
    354   };
    355   template<typename T>
    356   void f1(const ArgType& = ArgType());
    357   void f2();
    358   void bar() {
    359     f1<int>();
    360     f2();
    361   }
    362   // CHECK: call void @_ZN5test97ArgTypeD1Ev(%"struct.test9::ArgType"* %
    363   // CHECK: call void @_ZN5test92f2Ev()
    364 }
    365 
    366 namespace test10 {
    367   // We used to crash trying to replace _ZN6test106OptionD1Ev with
    368   // _ZN6test106OptionD2Ev twice.
    369   struct Option {
    370     virtual ~Option() {}
    371   };
    372   template <class DataType> class opt : public Option {};
    373   template class opt<int>;
    374   // CHECK-LABEL: define zeroext i1 @_ZN6test1016handleOccurrenceEv(
    375   bool handleOccurrence() {
    376     // CHECK: call void @_ZN6test106OptionD2Ev(
    377     Option x;
    378     return true;
    379   }
    380 }
    381 
    382 // Checks from test3:
    383 
    384   // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr
    385   // CHECK: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
    386   // CHECK: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]]
    387   // CHECK: ret void
    388   // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
    389   // CHECK-NEXT: cleanup
    390   // CHECK: call void @_ZdlPv({{.*}}) [[NUW]]
    391   // CHECK: resume { i8*, i32 }
    392 
    393   // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev(
    394   // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
    395   // CHECK: call void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
    396   // CHECK: ret void
    397 
    398   // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev(
    399   // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
    400   // CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev(
    401   // CHECK: ret void
    402 
    403   // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
    404   // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
    405   // CHECK: call void @_ZN5test312_GLOBAL__N_11CD2Ev(
    406   // CHECK: ret void
    407 
    408   // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
    409   // CHECK: invoke void @_ZN5test31BD2Ev(
    410   // CHECK: call void @_ZN5test31AD2Ev(
    411   // CHECK: ret void
    412 
    413   // CHECK: declare void @_ZN5test31BD2Ev(
    414   // CHECK: declare void @_ZN5test31AD2Ev(
    415 
    416   // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
    417   // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
    418   // CHECK: call void @_ZdlPv({{.*}}) [[NUW]]
    419   // CHECK: ret void
    420   // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
    421   // CHECK-NEXT: cleanup
    422   // CHECK: call void @_ZdlPv({{.*}}) [[NUW]]
    423   // CHECK: resume { i8*, i32 }
    424 
    425   // CHECK-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev(
    426   // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
    427   // CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev(
    428   // CHECK: ret void
    429 
    430   // CHECK: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}}
    431