diff options
Diffstat (limited to 'clang')
6 files changed, 45 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index f3eaef369a6..454cc5e3e77 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2309,13 +2309,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, 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 diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 037b1351c0f..5b4017cad37 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -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 VarDecl &D, ParamValue Arg, 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(); diff --git a/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp b/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp index 9d47d1706bb..164fda3c1c3 100644 --- a/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp +++ b/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp @@ -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: diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp index a576f0c3d7e..cd453b68e3b 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -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 diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp index 480ae8cfbbe..eaf1e3d6c3e 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -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"* diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp index aaee39c51db..b97c432f5e0 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp @@ -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 +} |