Author: rnk Date: Tue May 3 13:44:29 2016 New Revision: 268418 URL: http://llvm.org/viewvc/llvm-project?rev=268418&view=rev Log: [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 Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=268418&r1=268417&r2=268418&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue May 3 13:44:29 2016 @@ -274,7 +274,7 @@ RValue CodeGenFunction::EmitCXXMemberOrO if (MD->isVirtual()) { This = CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall( - *this, MD, This, UseVirtualCall); + *this, CalleeDecl, This, UseVirtualCall); } return EmitCXXMemberOrOperatorCall(MD, Callee, ReturnValue, This.getPointer(), Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp?rev=268418&r1=268417&r2=268418&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Tue May 3 13:44:29 2016 @@ -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]]) +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits