From 73c89ce83ee16759f4b252d030b466e697f9fac6 Mon Sep 17 00:00:00 2001 From: Reid Kleckner <rnk@google.com> Date: Tue, 3 May 2016 18:44:29 +0000 Subject: [PATCH] [MS] Pass CalleeDecl to adjustThisArgumentForVirtualFunctionCall If we are devirtualizing, then we want to compute the 'this' adjustment of the devirtualized target, not the adjustment of the base's method definition, which is usually zero. Fixes PR27621 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@268418 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExprCXX.cpp | 2 +- .../microsoft-abi-virtual-inheritance.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index a90610f5927..c6f46c3969b 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -274,7 +274,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( if (MD->isVirtual()) { This = CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall( - *this, MD, This, UseVirtualCall); + *this, CalleeDecl, This, UseVirtualCall); } return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp index 8897a384430..f4a6e30119b 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -481,3 +481,21 @@ 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* %1, i32 4 +// CHECK: call x86_thiscallcc void @"\01?g@C@pr27621@@UAEXXZ"(i8* %[[B_i8]]) +} -- GitLab