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 {
foobartest1::foobar29   foobar() {}
~foobartest1::foobar30   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 {
foobartest2::foobar45   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 {
~Atest3::__anonf0a601da0111::A59   ~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 {
~Atest4::A83     virtual ~A() {}
84   };
85   struct B : public A{
~Btest4::B86     ~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 {
~Atest5::A98     virtual ~A() {}
99   };
100   namespace {
101   struct B : public A{
~Btest5::__anonf0a601da0211::B102     ~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 {
~Btest6::__anonf0a601da0311::B116     ~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 {
~Atest7::A130     ~A() {}
131   };
132   class B : A<int> {
133     ~B();
134   };
135   template class A<int>;
~B()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   };
~foo()147   foo::~foo() {}
148   struct bar : public foo {
149     ~bar();
150   };
~bar()151   bar::~bar() {}
152   struct zed : public bar {};
153   zed foo;
154 }
155 
156 namespace test9 {
157 struct foo {
~footest9::foo158   __attribute__((stdcall)) ~foo() {
159   }
160 };
161 
162 struct bar : public foo {};
163 
zed()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:
B()184   B()
185       : A(0) {
186   }
~B()187   __attribute__((always_inline)) ~B() {
188   }
189 };
190 
191 extern template class B<char>;
192 
193 class C : B<char> {
194 };
195 
196 void
fn1()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 };
~bar()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>
~foo()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 };
~bar()227 bar::~bar() {}
228 struct foo : public bar {
229   ~foo();
230 };
~foo()231 foo::~foo() {}
232 // CHECK6: @_ZN6test113fooD2Ev = alias {{.*}} @_ZN6test113barD2Ev
233 // CHECK6: @_ZN6test113fooD1Ev = alias {{.*}} @_ZN6test113fooD2Ev
234 }
235 
236 namespace test12 {
237 template <int>
238 struct foo {
~footest12::foo239   ~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