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