1 // RUN: %clang_cc1 -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s 2 3 // CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [ 4 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany1@@3US@@A", i32 0, i32 0) }, 5 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany2@@3US@@A", i32 0, i32 0) }, 6 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Es@?$ExportedTemplate@H@@2US@@A@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) }, 7 // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ", i8* bitcast (%class.A* @"\01?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 } 9 // CHECK: ] 10 11 struct S { 12 S(); 13 ~S(); 14 }; 15 16 S s; 17 18 // CHECK: define internal void @"\01??__Es@@YAXXZ"() 19 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" 20 // CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ") 21 // CHECK: ret void 22 23 // CHECK: define internal void @"\01??__Fs@@YAXXZ"() 24 // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ" 25 // CHECK: ret void 26 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 void @"\01??__Eselectany1@@YAXXZ"() {{.*}} comdat 32 // CHECK-NOT: @"\01??_Bselectany1 33 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" 34 // CHECK: ret void 35 // CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"() {{.*}} comdat 36 // CHECK-NOT: @"\01??_Bselectany2 37 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" 38 // CHECK: ret void 39 40 // The implicitly instantiated static data member should have initializer 41 // comdat associative with the global. 42 template <typename T> struct __declspec(dllexport) ExportedTemplate { 43 static S s; 44 }; 45 template <typename T> S ExportedTemplate<T>::s; 46 void useExportedTemplate(ExportedTemplate<int> x) { 47 (void)x.s; 48 } 49 50 void StaticLocal() { 51 static S TheS; 52 } 53 54 // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"() 55 // CHECK: load i32, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" 56 // CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" 57 // CHECK: ret 58 59 void MultipleStatics() { 60 static S S1; 61 static S S2; 62 static S S3; 63 static S S4; 64 static S S5; 65 static S S6; 66 static S S7; 67 static S S8; 68 static S S9; 69 static S S10; 70 static S S11; 71 static S S12; 72 static S S13; 73 static S S14; 74 static S S15; 75 static S S16; 76 static S S17; 77 static S S18; 78 static S S19; 79 static S S20; 80 static S S21; 81 static S S22; 82 static S S23; 83 static S S24; 84 static S S25; 85 static S S26; 86 static S S27; 87 static S S28; 88 static S S29; 89 static S S30; 90 static S S31; 91 static S S32; 92 static S S33; 93 static S S34; 94 static S S35; 95 } 96 // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"() 97 // CHECK: load i32, i32* @"\01?$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 103 // ... 104 // CHECK: and i32 {{.*}}, -2147483648 105 // CHECK: load i32, i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ (at) 4IA.1" 106 // CHECK: and i32 {{.*}}, 1 107 // CHECK: and i32 {{.*}}, 2 108 // CHECK: and i32 {{.*}}, 4 109 // CHECK: ret 110 111 // Force WeakODRLinkage by using templates 112 class A { 113 public: 114 A() {} 115 ~A() {} 116 int a; 117 }; 118 119 template<typename T> 120 class B { 121 public: 122 static A foo; 123 }; 124 125 template<typename T> A B<T>::foo; 126 127 inline S &UnreachableStatic() { 128 if (0) { 129 static S s; // bit 1 130 return s; 131 } 132 static S s; // bit 2 133 return s; 134 } 135 136 // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat 137 // CHECK: and i32 {{.*}}, 2 138 // CHECK: or i32 {{.*}}, 2 139 // CHECK: ret 140 141 inline S &getS() { 142 static S TheS; 143 return TheS; 144 } 145 146 // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"() {{.*}} comdat 147 // CHECK: load i32, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" 148 // CHECK: and i32 {{.*}}, 1 149 // CHECK: icmp ne i32 {{.*}}, 0 150 // CHECK: br i1 151 // init: 152 // CHECK: or i32 {{.*}}, 1 153 // CHECK: store i32 {{.*}}, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" 154 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"(%struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A") 155 // CHECK: call i32 @atexit(void ()* @"\01??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ") 156 // CHECK: br label 157 // init.end: 158 // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A" 159 160 inline int enum_in_function() { 161 // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"() {{.*}} comdat 162 static enum e { foo, bar, baz } x; 163 // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A" 164 static int y; 165 // CHECK: @"\01?y@?1??enum_in_function@@YAHXZ@4HA" 166 return x + y; 167 }; 168 169 struct T { 170 enum e { foo, bar, baz }; 171 int enum_in_struct() { 172 // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"({{.*}}) {{.*}} comdat 173 static int x; 174 // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA" 175 return x++; 176 } 177 }; 178 179 inline int switch_test(int x) { 180 // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x) {{.*}} comdat 181 switch (x) { 182 static int a; 183 // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA" 184 case 0: 185 a++; 186 return 1; 187 case 1: 188 static int b; 189 // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA" 190 return b++; 191 case 2: { 192 static int c; 193 // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA" 194 return b + c++; 195 } 196 }; 197 } 198 199 int f(); 200 inline void switch_test2() { 201 // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"() {{.*}} comdat 202 // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA" 203 switch (1) default: static int x = f(); 204 } 205 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 209 // incorrect. 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>; 214 215 inline int switch_test3() { 216 // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"() {{.*}} comdat 217 static int local; 218 // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA" 219 return local++; 220 } 221 } 222 223 void force_usage() { 224 UnreachableStatic(); 225 getS(); 226 (void)B<int>::foo; // (void) - force usage 227 enum_in_function(); 228 (void)&T::enum_in_struct; 229 switch_test(1); 230 switch_test2(); 231 DynamicDLLImportInitVSMangling::switch_test3(); 232 } 233 234 // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat 235 // CHECK-NOT: and 236 // CHECK-NOT: ?_Bfoo@ 237 // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" 238 // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ") 239 // CHECK: ret void 240 241 // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"({{.*}}) {{.*}} comdat 242 243 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) {{.*}} comdat 244 245 // CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ" 246 // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo 247 // CHECK: ret void 248 249 // CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp() 250 // CHECK: call void @"\01??__Es@@YAXXZ"() 251 // CHECK: ret void 252