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