llvm-project/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
David Majnemer 34b4989658 MS ABI: Disambiguate the manglings for global guard variables
If a guard variable will be created for an entity at global scope,
then we cannot rely on the scope depth to disambiguate names for us.

Instead, mangle the entire variable into the guard to ensure it's uniqueness.

llvm-svn: 203151
2014-03-06 19:57:36 +00:00

157 lines
4.0 KiB
C++

// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
// CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"
// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
struct S {
S();
~S();
};
S s;
// CHECK: define internal void @"\01??__Es@@YAXXZ"() [[NUW:#[0-9]+]]
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ")
// CHECK: ret void
// CHECK: define internal void @"\01??__Fs@@YAXXZ"() [[NUW]] {
// CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ"
// CHECK: ret void
void StaticLocal() {
static S TheS;
}
// CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"()
// CHECK: load i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
// CHECK: ret
void MultipleStatics() {
static S S1;
static S S2;
static S S3;
static S S4;
static S S5;
static S S6;
static S S7;
static S S8;
static S S9;
static S S10;
static S S11;
static S S12;
static S S13;
static S S14;
static S S15;
static S S16;
static S S17;
static S S18;
static S S19;
static S S20;
static S S21;
static S S22;
static S S23;
static S S24;
static S S25;
static S S26;
static S S27;
static S S28;
static S S29;
static S S30;
static S S31;
static S S32;
static S S33;
static S S34;
static S S35;
}
// CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"()
// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA"
// CHECK: and i32 {{.*}}, 1
// CHECK: and i32 {{.*}}, 2
// CHECK: and i32 {{.*}}, 4
// CHECK: and i32 {{.*}}, 8
// CHECK: and i32 {{.*}}, 16
// ...
// CHECK: and i32 {{.*}}, -2147483648
// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA1"
// CHECK: and i32 {{.*}}, 1
// CHECK: and i32 {{.*}}, 2
// CHECK: and i32 {{.*}}, 4
// CHECK: ret
// Force WeakODRLinkage by using templates
class A {
public:
A() {}
~A() {}
};
template<typename T>
class B {
public:
static A foo;
};
template<typename T> A B<T>::foo;
inline S &UnreachableStatic() {
if (0) {
static S s; // bit 1
return s;
}
static S s; // bit 2
return s;
}
// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
// CHECK: and i32 {{.*}}, 2
// CHECK: or i32 {{.*}}, 2
// CHECK: ret
inline S &getS() {
static S TheS;
return TheS;
}
// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?getS@@YAAAUS@@XZ"
// CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: and i32 {{.*}}, 1
// CHECK: icmp ne i32 {{.*}}, 0
// CHECK: br i1
// init:
// CHECK: or i32 {{.*}}, 1
// CHECK: store i32 {{.*}}, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"(%struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
// CHECK: call i32 @atexit(void ()* @"\01??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
// CHECK: br label
// init.end:
// CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
void force_usage() {
UnreachableStatic();
getS();
(void)B<int>::foo; // (void) - force usage
}
// CHECK: define internal void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() [[NUW]]
// CHECK: load i32* @"\01??_Bfoo@?$B@H@@2VA@@A@5"
// CHECK: store i32 {{.*}}, i32* @"\01??_Bfoo@?$B@H@@2VA@@A@5"
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
// CHECK: ret void
// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"
// CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo
// CHECK: ret void
// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] {
// CHECK: call void @"\01??__Es@@YAXXZ"()
// CHECK: ret void
// CHECK: attributes [[NUW]] = { nounwind }