diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 98ed1b3b2f..6345ca34ba 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -677,13 +677,25 @@ CodeGenFunction::EmitClassCopyAssignment(llvm::Value *Dest, llvm::Value *Src, void CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) { const CXXConstructorDecl *Ctor = cast(CurGD.getDecl()); + CXXCtorType CtorType = CurGD.getCtorType(); + (void) CtorType; + const CXXRecordDecl *ClassDecl = Ctor->getParent(); assert(!ClassDecl->hasUserDeclaredCopyConstructor() && "SynthesizeCXXCopyConstructor - copy constructor has definition already"); assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor"); llvm::Value *ThisPtr = LoadCXXThis(); - llvm::Value *SrcPtr = Builder.CreateLoad(GetAddrOfLocalVar(Args[1].first)); + + // Find the source pointer. + unsigned SrcArgIndex = Args.size() - 1; + assert(CtorType == Ctor_Base || SrcArgIndex == 1); + assert(CtorType != Ctor_Base || + (ClassDecl->getNumVBases() != 0 && SrcArgIndex == 2) || + SrcArgIndex == 1); + + llvm::Value *SrcPtr = + Builder.CreateLoad(GetAddrOfLocalVar(Args[SrcArgIndex].first)); for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); Base != ClassDecl->bases_end(); ++Base) { diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp index e0709055cd..a8dc7fcec7 100644 --- a/test/CodeGenCXX/constructors.cpp +++ b/test/CodeGenCXX/constructors.cpp @@ -92,3 +92,15 @@ D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} // CHECK: call void @_ZN10ValueClassC1Eii( // CHECK: call void @_ZN1AC2E10ValueClass( // CHECK: call void @_ZN6MemberC1Ei( + + +// PR6622: this shouldn't crash +namespace test0 { + struct A {}; + struct B : virtual A { int x; }; + struct C : B {}; + + void test(C &in) { + C tmp = in; + } +}