Author: rnk Date: Wed Sep 7 13:21:30 2016 New Revision: 280836 URL: http://llvm.org/viewvc/llvm-project?rev=280836&view=rev Log: [MS] Fix prologue this adjustment when 'this' is passed indirectly
Move the logic for doing this from the ABI argument lowering into EmitParmDecl, which runs for all parameters. Our codegen is slightly suboptimal in this case, as we may leave behind a dead store after optimization, but it's 32-bit inalloca, and this fixes the bug in a robust way. Fixes PR30293 Modified: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/constructor-destructor-return-this.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Sep 7 13:21:30 2016 @@ -2309,13 +2309,6 @@ void CodeGenFunction::EmitFunctionProlog if (isPromoted) V = emitArgumentDemotion(*this, Arg, V); - if (const CXXMethodDecl *MD = - dyn_cast_or_null<CXXMethodDecl>(CurCodeDecl)) { - if (MD->isVirtual() && Arg == CXXABIThisDecl) - V = CGM.getCXXABI(). - adjustThisParameterInVirtualFunctionPrologue(*this, CurGD, V); - } - // Because of merging of function types from multiple decls it is // possible for the type of an argument to not match the corresponding // type in the function type. Since we are codegening the callee Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Sep 7 13:21:30 2016 @@ -13,6 +13,7 @@ #include "CodeGenFunction.h" #include "CGBlocks.h" +#include "CGCXXABI.h" #include "CGCleanup.h" #include "CGDebugInfo.h" #include "CGOpenCLRuntime.h" @@ -1769,6 +1770,24 @@ void CodeGenFunction::EmitParmDecl(const setBlockContextParameter(IPD, ArgNo, Arg.getDirectValue()); return; } + + // Apply any prologue 'this' adjustments required by the ABI. Be careful to + // handle the case where 'this' is passed indirectly as part of an inalloca + // struct. + if (const CXXMethodDecl *MD = + dyn_cast_or_null<CXXMethodDecl>(CurCodeDecl)) { + if (MD->isVirtual() && IPD == CXXABIThisDecl) { + llvm::Value *This = Arg.isIndirect() + ? Builder.CreateLoad(Arg.getIndirectAddress()) + : Arg.getDirectValue(); + This = CGM.getCXXABI().adjustThisParameterInVirtualFunctionPrologue( + *this, CurGD, This); + if (Arg.isIndirect()) + Builder.CreateStore(This, Arg.getIndirectAddress()); + else + Arg = ParamValue::forDirect(This); + } + } } Address DeclPtr = Address::invalid(); Modified: cfe/trunk/test/CodeGenCXX/constructor-destructor-return-this.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/constructor-destructor-return-this.cpp?rev=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/constructor-destructor-return-this.cpp (original) +++ cfe/trunk/test/CodeGenCXX/constructor-destructor-return-this.cpp Wed Sep 7 13:21:30 2016 @@ -111,7 +111,7 @@ D::~D() { } // CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this) // CHECKMS-LABEL: define x86_thiscallcc %class.D* @"\01??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived) -// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D*) +// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D* %this) class E { public: Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp?rev=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp Wed Sep 7 13:21:30 2016 @@ -196,7 +196,7 @@ struct E : virtual C { int e; }; struct F : D, E { ~F(); int f; }; F::~F() { -// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*) +// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*{{[^,]*}}) // Do an adjustment from C vbase subobject to F as though F was the // complete type. // CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 -20 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=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp Wed Sep 7 13:21:30 2016 @@ -283,7 +283,7 @@ struct D : virtual Z, B, C { } d; D::~D() { - // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*) + // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}}) // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8* // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"* Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp?rev=280836&r1=280835&r2=280836&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp Wed Sep 7 13:21:30 2016 @@ -177,3 +177,26 @@ void fop(C &c) { } } + +namespace pr30293 { +struct NonTrivial { + ~NonTrivial(); + int x; +}; +struct A { virtual void f(); }; +struct B { virtual void __cdecl g(NonTrivial); }; +struct C final : A, B { + void f() override; + void __cdecl g(NonTrivial) override; +}; +C *whatsthis; +void C::f() { g(NonTrivial()); } +void C::g(NonTrivial o) { + whatsthis = this; +} + +// BITCODE-LABEL: define void @"\01?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca) +// BITCODE: %[[this1:[^ ]*]] = load i8*, i8** %[[thisaddr:[^ ]*]], align 4 +// BITCODE-NEXT: %[[this2:[^ ]*]] = getelementptr inbounds i8, i8* %[[this1]], i32 -4 +// BITCODE-NEXT: store i8* %[[this2]], i8** %[[thisaddr]], align 4 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits