Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
      2 
      3 // RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns > %t
      4 // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t %s
      5 // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t %s
      6 // RUN: FileCheck --check-prefix=CHECK3 --input-file=%t %s
      7 // RUN: FileCheck --check-prefix=CHECK4 --input-file=%t %s
      8 // RUN: FileCheck --check-prefix=CHECK5 --input-file=%t %s
      9 // RUN: FileCheck --check-prefix=CHECK6 --input-file=%t %s
     10 
     11 // RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck --check-prefix=COFF %s
     12 
     13 namespace test1 {
     14 // Test that we produce the apropriate comdats when creating aliases to
     15 // weak_odr constructors and destructors.
     16 
     17 // CHECK1: @_ZN5test16foobarIvEC1Ev = weak_odr alias void {{.*}} @_ZN5test16foobarIvEC2Ev
     18 // CHECK1: @_ZN5test16foobarIvED1Ev = weak_odr alias void (%"struct.test1::foobar"*), void (%"struct.test1::foobar"*)* @_ZN5test16foobarIvED2Ev
     19 // CHECK1: define weak_odr void @_ZN5test16foobarIvEC2Ev({{.*}} comdat($_ZN5test16foobarIvEC5Ev)
     20 // CHECK1: define weak_odr void @_ZN5test16foobarIvED2Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
     21 // CHECK1: define weak_odr void @_ZN5test16foobarIvED0Ev({{.*}} comdat($_ZN5test16foobarIvED5Ev)
     22 // CHECK1-NOT: comdat
     23 
     24 // COFF doesn't support comdats with arbitrary names (C5/D5).
     25 // COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC2Ev({{.*}} comdat align
     26 // COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC1Ev({{.*}} comdat align
     27 // COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED2Ev({{.*}} comdat align
     28 // COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED0Ev({{.*}} comdat align
     29 
     30 template <typename T>
     31 struct foobar {
     32   foobar() {}
     33   virtual ~foobar() {}
     34 };
     35 
     36 template struct foobar<void>;
     37 }
     38 
     39 namespace test2 {
     40 // test that when the destrucor is linkonce_odr we just replace every use of
     41 // C1 with C2.
     42 
     43 // CHECK1: define internal void @__cxx_global_var_init()
     44 // CHECK1: call void @_ZN5test26foobarIvEC2Ev
     45 // CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev({{.*}} comdat align
     46 void g();
     47 template <typename T> struct foobar {
     48   foobar() { g(); }
     49 };
     50 foobar<void> x;
     51 }
     52 
     53 namespace test3 {
     54 // test that instead of an internal alias we just use the other destructor
     55 // directly.
     56 
     57 // CHECK1: define internal void @__cxx_global_var_init.1()
     58 // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11AD2Ev
     59 // CHECK1: define internal void @_ZN5test312_GLOBAL__N_11AD2Ev(
     60 namespace {
     61 struct A {
     62   ~A() {}
     63 };
     64 
     65 struct B : public A {};
     66 }
     67 
     68 B x;
     69 }
     70 
     71 namespace test4 {
     72   // Test that we don't produce aliases from B to A. We cannot because we cannot
     73   // guarantee that they will be present in every TU. Instead, we just call
     74   // A's destructor directly.
     75 
     76   // CHECK1: define internal void @__cxx_global_var_init.2()
     77   // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev
     78   // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align
     79 
     80   // test that we don't do this optimization at -O0 so that the debugger can
     81   // see both destructors.
     82   // NOOPT: define internal void @__cxx_global_var_init.2()
     83   // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev
     84   // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align
     85   struct A {
     86     virtual ~A() {}
     87   };
     88   struct B : public A{
     89     ~B() {}
     90   };
     91   B X;
     92 }
     93 
     94 namespace test5 {
     95   // similar to test4, but with an internal B.
     96 
     97   // CHECK2: define internal void @__cxx_global_var_init.3()
     98   // CHECK2: call i32 @__cxa_atexit{{.*}}_ZN5test51AD2Ev
     99   // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev({{.*}} comdat align
    100   struct A {
    101     virtual ~A() {}
    102   };
    103   namespace {
    104   struct B : public A{
    105     ~B() {}
    106   };
    107   }
    108   B X;
    109 }
    110 
    111 namespace test6 {
    112   // Test that we use ~A directly, even when ~A is not defined. The symbol for
    113   // ~B would have been internal and still contain a reference to ~A.
    114   struct A {
    115     virtual ~A();
    116   };
    117   namespace {
    118   struct B : public A {
    119     ~B() {}
    120   };
    121   }
    122   B X;
    123   // CHECK3: define internal void @__cxx_global_var_init.4()
    124   // CHECK3: call i32 @__cxa_atexit({{.*}}@_ZN5test61AD2Ev
    125 }
    126 
    127 namespace test7 {
    128   // Test that we don't produce an alias from ~B to ~A<int> (or crash figuring
    129   // out if we should).
    130   // pr17875.
    131   // CHECK3: define void @_ZN5test71BD2Ev
    132   template <typename> struct A {
    133     ~A() {}
    134   };
    135   class B : A<int> {
    136     ~B();
    137   };
    138   template class A<int>;
    139   B::~B() {}
    140 }
    141 
    142 namespace test8 {
    143   // Test that we replace ~zed with ~bar which is an alias to ~foo.
    144   // CHECK4: @_ZN5test83barD2Ev = alias {{.*}} @_ZN5test83fooD2Ev
    145   // CHECK4: define internal void @__cxx_global_var_init.5()
    146   // CHECK4: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev
    147   struct foo {
    148     ~foo();
    149   };
    150   foo::~foo() {}
    151   struct bar : public foo {
    152     ~bar();
    153   };
    154   bar::~bar() {}
    155   struct zed : public bar {};
    156   zed foo;
    157 }
    158 
    159 namespace test9 {
    160 struct foo {
    161   __attribute__((stdcall)) ~foo() {
    162   }
    163 };
    164 
    165 struct bar : public foo {};
    166 
    167 void zed() {
    168   // Test that we produce a call to bar's destructor. We used to call foo's, but
    169   // it has a different calling conversion.
    170   // CHECK4: call void @_ZN5test93barD2Ev
    171   bar ptr;
    172 }
    173 }
    174 
    175 // CHECK5: @_ZTV1C = linkonce_odr unnamed_addr constant [4 x i8*] [{{[^@]*}}@_ZTI1C {{[^@]*}}@_ZN1CD2Ev {{[^@]*}}@_ZN1CD0Ev {{[^@]*}}]
    176 // r194296 replaced C::~C with B::~B without emitting the later.
    177 
    178 class A {
    179 public:
    180   A(int);
    181   virtual ~A();
    182 };
    183 
    184 template <class>
    185 class B : A {
    186 public:
    187   B()
    188       : A(0) {
    189   }
    190   __attribute__((always_inline)) ~B() {
    191   }
    192 };
    193 
    194 extern template class B<char>;
    195 
    196 class C : B<char> {
    197 };
    198 
    199 void
    200 fn1() {
    201   new C;
    202 }
    203 
    204 namespace test10 {
    205 // Test that if a destructor is in a comdat, we don't try to emit is as an
    206 // alias to a base class destructor.
    207 struct bar {
    208   ~bar();
    209 };
    210 bar::~bar() {
    211 }
    212 } // closing the namespace causes ~bar to be sent to CodeGen
    213 namespace test10 {
    214 template <typename T>
    215 struct foo : public bar {
    216   ~foo();
    217 };
    218 template <typename T>
    219 foo<T>::~foo() {}
    220 template class foo<int>;
    221 // CHECK5: define weak_odr void @_ZN6test103fooIiED2Ev({{.*}} comdat($_ZN6test103fooIiED5Ev)
    222 }
    223 
    224 namespace test11 {
    225 // Test that when we don't have to worry about COMDATs we produce an alias
    226 // from complate to base and from base to base class base.
    227 struct bar {
    228   ~bar();
    229 };
    230 bar::~bar() {}
    231 struct foo : public bar {
    232   ~foo();
    233 };
    234 foo::~foo() {}
    235 // CHECK6: @_ZN6test113fooD2Ev = alias {{.*}} @_ZN6test113barD2Ev
    236 // CHECK6: @_ZN6test113fooD1Ev = alias {{.*}} @_ZN6test113fooD2Ev
    237 }
    238 
    239 namespace test12 {
    240 template <int>
    241 struct foo {
    242   ~foo() { delete this; }
    243 };
    244 
    245 template class foo<1>;
    246 // CHECK6: @_ZN6test123fooILi1EED1Ev = weak_odr alias {{.*}} @_ZN6test123fooILi1EED2Ev
    247 // CHECK6: define weak_odr void @_ZN6test123fooILi1EED2Ev({{.*}}) {{.*}} comdat($_ZN6test123fooILi1EED5Ev)
    248 }
    249