f4a2713ac8
Change-Id: Ia40e9ffdf29b5dab2f122f673ff6802a58bc690f
154 lines
3.8 KiB
C++
154 lines
3.8 KiB
C++
// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -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@@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@?1??StaticLocal@@YAXXZ@4IA"
|
|
// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??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@?1??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@?1??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@@YAXXZ"() [[NUW]]
|
|
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
|
|
// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@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@@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 }
|