From: David Majnemer Date: Wed, 15 Oct 2014 04:54:54 +0000 (+0000) Subject: MS ABI: Use the correct this arg when generating implicit array copy ctor X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=80a4e4ae40406357bb09d0d6c24a230b9e178fca;p=clang MS ABI: Use the correct this arg when generating implicit array copy ctor We assumed the last argument of the copy constructor was the this pointer. However, this is not the case under the MS ABI. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219775 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index d7010c7e91..1bba4a70a1 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -580,9 +580,8 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, CXXConstructExpr *CE = dyn_cast(MemberInit->getInit()); if (BaseElementTy.isPODType(CGF.getContext()) || (CE && CE->getConstructor()->isTrivial())) { - // Find the source pointer. We know it's the last argument because - // we know we're in an implicit copy constructor. - unsigned SrcArgIndex = Args.size() - 1; + unsigned SrcArgIndex = + CGF.CGM.getCXXABI().getSrcArgforCopyCtor(Constructor, Args); llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); diff --git a/test/CodeGenCXX/pr20897.cpp b/test/CodeGenCXX/pr20897.cpp index 06828c0ec0..49d669bd7e 100644 --- a/test/CodeGenCXX/pr20897.cpp +++ b/test/CodeGenCXX/pr20897.cpp @@ -15,3 +15,19 @@ struct __declspec(dllexport) Derived : virtual Base { bool a : 1; bool b : 1; }; + +// __declspec(dllexport) causes us to export the implicit copy constructor. +struct __declspec(dllexport) Derived2 : virtual Base { +// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc %struct.Derived2* @"\01??0Derived2@@QAE@ABU0@@Z" +// CHECK: %[[this:.*]] = load %struct.Derived2** {{.*}} +// CHECK-NEXT: store %struct.Derived2* %[[this]], %struct.Derived2** %[[retval:.*]] +// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived2* %[[this]], i32 0, i32 1 +// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived2** {{.*}} +// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived2* %[[src_load:.*]], i32 0, i32 1 +// CHECK-NEXT: %[[dest_a_bitcast:.*]] = bitcast [1 x i32]* %[[dest_a_gep]] to i8* +// CHECK-NEXT: %[[src_a_bitcast:.*]] = bitcast [1 x i32]* %[[src_a_gep]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[dest_a_bitcast]], i8* %[[src_a_bitcast]], i32 4, i32 4, i1 false) +// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived2** %[[retval]] +// CHECK-NEXT: ret %struct.Derived2* %[[dest_this]] + int Array[1]; +};