diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp | |
parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) |
Notes
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp')
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp index 8897a384430c..480ae8cfbbec 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -481,3 +481,43 @@ C::C() : B() {} // CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[B_i8]], i32 4 // CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false) } + +namespace pr27621 { +// Devirtualization through a static_cast used to make us compute the 'this' +// adjustment for B::g instead of C::g. When we directly call C::g, 'this' is a +// B*, and the prologue of C::g will adjust it to a C*. +struct A { virtual void f(); }; +struct B { virtual void g(); }; +struct C final : A, B { + virtual void h(); + void g() override; +}; +void callit(C *p) { + static_cast<B*>(p)->g(); +} +// CHECK-LABEL: define void @"\01?callit@pr27621@@YAXPAUC@1@@Z"(%"struct.pr27621::C"* %{{.*}}) +// CHECK: %[[B_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 4 +// CHECK: call x86_thiscallcc void @"\01?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]]) +} + +namespace test6 { +class A {}; +class B : virtual A {}; +class C : virtual B { + virtual void m_fn1(); + float field; +}; +class D : C { + D(); +}; +D::D() : C() {} +// CHECK-LABEL: define x86_thiscallcc %"class.test6::D"* @"\01??0D@test6@@AAE@XZ"( +// CHECK: %[[THIS:.*]] = load %"class.test6::D"*, %"class.test6::D"** +// CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] + +// CHECK: %[[SKIP_VBASES]] +// CHECK: %[[C:.*]] = bitcast %"class.test6::D"* %[[THIS]] to %"class.test6::C"* +// CHECK: %[[C_i8:.*]] = bitcast %"class.test6::C"* %[[C]] to i8* +// CHECK: %[[FIELD:.*]] = getelementptr inbounds i8, i8* %[[C_i8]], i32 8 +// CHECK: call void @llvm.memset.p0i8.i32(i8* %[[FIELD]], i8 0, i32 4, i32 4, i1 false) +} |