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