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