r280836 - [MS] Fix prologue this adjustment when 'this' is passed indirectly

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 7 11:21:30 PDT 2016


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 at XZ"(%class.D* returned %this, i32 %is_most_derived)
-// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE at XZ"(%class.D*)
+// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE at 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 at test2@@UAE at XZ"(%"struct.test2::F"*)
+// CHECK-LABEL: define x86_thiscallcc void @"\01??1F at test2@@UAE at 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 at diamond@@UAE at XZ"(%"struct.diamond::D"*)
+  // CHECK-LABEL: define x86_thiscallcc void @"\01??1D at diamond@@UAE at 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 at C@pr30293@@UAAXUNonTrivial at 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
+}




More information about the cfe-commits mailing list