1 // RUN: %clang_cc1 -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
3 // CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [
4 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany1@@3US@@A", i32 0, i32 0) },
5 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany2@@3US@@A", i32 0, i32 0) },
6 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
7 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ", i8* bitcast (%class.A* @"?foo@?$B@H@@2VA@@A" to i8*) },
8 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }
18 // CHECK: define internal void @"??__Es@@YAXXZ"()
19 // CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
20 // CHECK: call i32 @atexit(void ()* @"??__Fs@@YAXXZ")
23 // CHECK: define internal void @"??__Fs@@YAXXZ"()
24 // CHECK: call x86_thiscallcc void @"??1S@@QAE@XZ"
27 // These globals should have initializers comdat associative with the global.
28 // See @llvm.global_ctors above.
29 __declspec(selectany
) S selectany1
;
30 __declspec(selectany
) S selectany2
;
31 // CHECK: define linkonce_odr dso_local void @"??__Eselectany1@@YAXXZ"() {{.*}} comdat
32 // CHECK-NOT: @"??_Bselectany1
33 // CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
35 // CHECK: define linkonce_odr dso_local void @"??__Eselectany2@@YAXXZ"() {{.*}} comdat
36 // CHECK-NOT: @"??_Bselectany2
37 // CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
40 // The implicitly instantiated static data member should have initializer
41 // comdat associative with the global.
42 template <typename T
> struct __declspec(dllexport
) ExportedTemplate
{
45 template <typename T
> S ExportedTemplate
<T
>::s
;
46 void useExportedTemplate(ExportedTemplate
<int> x
) {
54 // CHECK-LABEL: define dso_local void @"?StaticLocal@@YAXXZ"()
55 // CHECK: load i32, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
56 // CHECK: store i32 {{.*}}, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
59 void MultipleStatics() {
96 // CHECK-LABEL: define dso_local void @"?MultipleStatics@@YAXXZ"()
97 // CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@YAXXZ@4IA"
98 // CHECK: and i32 {{.*}}, 1
99 // CHECK: and i32 {{.*}}, 2
100 // CHECK: and i32 {{.*}}, 4
101 // CHECK: and i32 {{.*}}, 8
102 // CHECK: and i32 {{.*}}, 16
104 // CHECK: and i32 {{.*}}, -2147483648
105 // CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@YAXXZ@4IA.1"
106 // CHECK: and i32 {{.*}}, 1
107 // CHECK: and i32 {{.*}}, 2
108 // CHECK: and i32 {{.*}}, 4
111 // Force WeakODRLinkage by using templates
125 template<typename T
> A B
<T
>::foo
;
127 inline S
&UnreachableStatic() {
136 // CHECK-LABEL: define linkonce_odr dso_local noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.S* @"?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat
137 // CHECK: and i32 {{.*}}, 2
138 // CHECK: or i32 {{.*}}, 2
146 // CHECK-LABEL: define linkonce_odr dso_local noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.S* @"?getS@@YAAAUS@@XZ"() {{.*}} comdat
147 // CHECK: load i32, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
148 // CHECK: and i32 {{.*}}, 1
149 // CHECK: icmp eq i32 {{.*}}, 0
152 // CHECK: or i32 {{.*}}, 1
153 // CHECK: store i32 {{.*}}, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
154 // CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"(%struct.S* {{[^,]*}} @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
155 // CHECK: call i32 @atexit(void ()* @"??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
158 // CHECK: ret %struct.S* @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
160 inline int enum_in_function() {
161 // CHECK-LABEL: define linkonce_odr dso_local noundef i32 @"?enum_in_function@@YAHXZ"() {{.*}} comdat
162 static enum e
{ foo
, bar
, baz
} x
;
163 // CHECK: @"?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
165 // CHECK: @"?y@?1??enum_in_function@@YAHXZ@4HA"
170 enum e
{ foo
, bar
, baz
};
171 int enum_in_struct() {
172 // CHECK-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef i32 @"?enum_in_struct@T@@QAEHXZ"({{.*}}) {{.*}} comdat
174 // CHECK: @"?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
179 inline int switch_test(int x
) {
180 // CHECK-LABEL: define linkonce_odr dso_local noundef i32 @"?switch_test@@YAHH@Z"(i32 noundef %x) {{.*}} comdat
183 // CHECK: @"?a@?3??switch_test@@YAHH@Z@4HA"
189 // CHECK: @"?b@?3??switch_test@@YAHH@Z@4HA"
193 // CHECK: @"?c@?4??switch_test@@YAHH@Z@4HA"
200 inline void switch_test2() {
201 // CHECK-LABEL: define linkonce_odr dso_local void @"?switch_test2@@YAXXZ"() {{.*}} comdat
202 // CHECK: @"?x@?2??switch_test2@@YAXXZ@4HA"
203 switch (1) default: static int x
= f();
206 namespace DynamicDLLImportInitVSMangling
{
207 // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
208 // dynamic initializer would cause subsequent static local numberings to be
210 struct NonPOD
{ NonPOD(); };
211 template <typename T
> struct A
{ static NonPOD x
; };
212 template <typename T
> NonPOD A
<T
>::x
;
213 template struct __declspec(dllimport
) A
<int>;
215 inline int switch_test3() {
216 // CHECK-LABEL: define linkonce_odr dso_local noundef i32 @"?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"() {{.*}} comdat
218 // CHECK: @"?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
226 (void)B
<int>::foo
; // (void) - force usage
228 (void)&T::enum_in_struct
;
231 DynamicDLLImportInitVSMangling::switch_test3();
234 // CHECK: define linkonce_odr dso_local void @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ"() {{.*}} comdat
236 // CHECK-NOT: ?_Bfoo@
237 // CHECK: call x86_thiscallcc noundef %class.A* @"??0A@@QAE@XZ"
238 // CHECK: call i32 @atexit(void ()* @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ")
241 // CHECK: define linkonce_odr dso_local x86_thiscallcc noundef %class.A* @"??0A@@QAE@XZ"({{.*}}) {{.*}} comdat
243 // CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) {{.*}} comdat
245 // CHECK: define internal void @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ"
246 // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"{{.*}}foo
249 // CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
250 // CHECK: call void @"??__Es@@YAXXZ"()