r217642 - MS ABI: Use the correct this arg when generating implict copy ctor

David Majnemer david.majnemer at gmail.com
Thu Sep 11 16:05:02 PDT 2014


Author: majnemer
Date: Thu Sep 11 18:05:02 2014
New Revision: 217642

URL: http://llvm.org/viewvc/llvm-project?rev=217642&view=rev
Log:
MS ABI: Use the correct this arg when generating implict copy ctor

We assumed that the incoming this argument would be the last argument.

However, this is not true under the MS ABI.

This fixes PR20897.

Added:
    cfe/trunk/test/CodeGenCXX/pr20897.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=217642&r1=217641&r2=217642&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Thu Sep 11 18:05:02 2014
@@ -384,6 +384,9 @@ public:
   virtual void EmitReturnFromThunk(CodeGenFunction &CGF,
                                    RValue RV, QualType ResultType);
 
+  virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
+                                      FunctionArgList &Args) const = 0;
+
   /// Gets the pure virtual member call function.
   virtual StringRef GetPureVirtualCallName() = 0;
 

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=217642&r1=217641&r2=217642&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Sep 11 18:05:02 2014
@@ -914,11 +914,12 @@ namespace {
   private:
 
     /// Get source argument for copy constructor. Returns null if not a copy
-    /// constructor. 
-    static const VarDecl* getTrivialCopySource(const CXXConstructorDecl *CD,
+    /// constructor.
+    static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
+                                               const CXXConstructorDecl *CD,
                                                FunctionArgList &Args) {
       if (CD->isCopyOrMoveConstructor() && CD->isDefaulted())
-        return Args[Args.size() - 1];
+        return Args[CGF.CGM.getCXXABI().getSrcArgforCopyCtor(CD, Args)];
       return nullptr;
     }
 
@@ -949,7 +950,7 @@ namespace {
   public:
     ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD,
                           FunctionArgList &Args)
-      : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CD, Args)),
+      : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
         ConstructorDecl(CD),
         MemcpyableCtor(CD->isDefaulted() &&
                        CD->isCopyOrMoveConstructor() &&

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=217642&r1=217641&r2=217642&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Sep 11 18:05:02 2014
@@ -208,6 +208,12 @@ public:
   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret,
                                        const ReturnAdjustment &RA) override;
 
+  size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
+                              FunctionArgList &Args) const override {
+    assert(!Args.empty() && "expected the arglist to not be empty!");
+    return Args.size() - 1;
+  }
+
   StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; }
   StringRef GetDeletedVirtualCallName() override
     { return "__cxa_deleted_virtual"; }

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=217642&r1=217641&r2=217642&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Sep 11 18:05:02 2014
@@ -50,6 +50,18 @@ public:
 
   bool isSRetParameterAfterThis() const override { return true; }
 
+  size_t getSrcArgforCopyCtor(const CXXConstructorDecl *CD,
+                              FunctionArgList &Args) const override {
+    assert(Args.size() >= 2 &&
+           "expected the arglist to have at least two args!");
+    // The 'most_derived' parameter goes second if the ctor is variadic and
+    // has v-bases.
+    if (CD->getParent()->getNumVBases() > 0 &&
+        CD->getType()->castAs<FunctionProtoType>()->isVariadic())
+      return 2;
+    return 1;
+  }
+
   StringRef GetPureVirtualCallName() override { return "_purecall"; }
   // No known support for deleted functions in MSVC yet, so this choice is
   // arbitrary.

Added: cfe/trunk/test/CodeGenCXX/pr20897.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pr20897.cpp?rev=217642&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pr20897.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/pr20897.cpp Thu Sep 11 18:05:02 2014
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+struct Base {};
+
+// __declspec(dllexport) causes us to export the implicit constructor.
+struct __declspec(dllexport) Derived : virtual Base {
+// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc %struct.Derived* @"\01??0Derived@@QAE at ABU0@@Z"
+// CHECK:      %[[this:.*]] = load %struct.Derived** {{.*}}
+// CHECK-NEXT: store %struct.Derived* %[[this]], %struct.Derived** %[[retval:.*]]
+// CHECK:      %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived* %[[this]], i32 0, i32 1
+// CHECK-NEXT: %[[src_load:.*]]   = load %struct.Derived** {{.*}}
+// CHECK-NEXT: %[[src_a_gep:.*]]  = getelementptr inbounds %struct.Derived* %[[src_load:.*]], i32 0, i32 1
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %[[dest_a_gep]], i8* %[[src_a_gep]], i64 1, i32 4, i1 false)
+// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived** %[[retval]]
+// CHECK-NEXT: ret %struct.Derived* %[[dest_this]]
+  bool a : 1;
+  bool b : 1;
+};





More information about the cfe-commits mailing list