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

Reply via email to