diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 7a452ec929d060d396a8da179860640f419b202a..78a29ad35f6b9bf69bdba5b3fc8ae22c50a5c76a 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -692,18 +692,6 @@ CodeGenFunction::SynthesizeCXXCopyConstructor(const FunctionArgList &Args) { llvm::Value *SrcObj = GetAddrOfLocalVar(SrcArg); llvm::Value *LoadOfSrc = Builder.CreateLoad(SrcObj); - for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(); - Base != ClassDecl->bases_end(); ++Base) { - // FIXME. copy constrution of virtual base NYI - if (Base->isVirtual()) - continue; - - CXXRecordDecl *BaseClassDecl - = cast(Base->getType()->getAs()->getDecl()); - EmitClassMemberwiseCopy(LoadOfThis, LoadOfSrc, ClassDecl, BaseClassDecl, - Base->getType()); - } - for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(), E = ClassDecl->field_end(); I != E; ++I) { const FieldDecl *Field = *I; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d7cbc17a7a5bd59436e1b3986ce97dab9c9e4971..af4245d21c5bdefb66a9af935a5b2d06487c65a1 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1546,6 +1546,11 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, FieldDecl *Field, CXXBaseOrMemberInitializer *&CXXMemberInit) { if (ImplicitInitKind == IIK_Copy) { + // FIXME: We shouldn't return early here. The reason we do it is that + // we don't handle copying arrays. + CXXMemberInit = 0; + return false; + ParmVarDecl *Param = Constructor->getParamDecl(0); QualType ParamType = Param->getType().getNonReferenceType(); @@ -4199,25 +4204,16 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, DeclContext *PreviousContext = CurContext; CurContext = CopyConstructor; - // C++ [class.copy] p209 - // Before the implicitly-declared copy constructor for a class is - // implicitly defined, all the implicitly-declared copy constructors - // for its base class and its non-static data members shall have been - // implicitly defined. - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(); - Base != ClassDecl->bases_end(); ++Base) { - CXXRecordDecl *BaseClassDecl - = cast(Base->getType()->getAs()->getDecl()); - if (CXXConstructorDecl *BaseCopyCtor = - BaseClassDecl->getCopyConstructor(Context, TypeQuals)) { - CheckDirectMemberAccess(Base->getSourceRange().getBegin(), - BaseCopyCtor, - PDiag(diag::err_access_copy_base) - << Base->getType()); - - MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor); - } + if (SetBaseOrMemberInitializers(CopyConstructor, 0, 0, /*AnyErrors=*/false)) { + Diag(CurrentLocation, diag::note_member_synthesized_at) + << CXXCopyConstructor << Context.getTagDeclType(ClassDecl); + CopyConstructor->setInvalidDecl(); + } else { + CopyConstructor->setUsed(); } + + // FIXME: Once we teach SetBaseOrMemberInitializers to copy fields, we can + // get rid of this code. for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), FieldEnd = ClassDecl->field_end(); Field != FieldEnd; ++Field) { diff --git a/clang/test/SemaCXX/constructor-initializer.cpp b/clang/test/SemaCXX/constructor-initializer.cpp index ff963a9bce2ade792a55af4b94cff8ee559aedf3..8e9e133d94cbdad8ad3ff49c2d19a11e4b12c8e2 100644 --- a/clang/test/SemaCXX/constructor-initializer.cpp +++ b/clang/test/SemaCXX/constructor-initializer.cpp @@ -183,9 +183,24 @@ struct B { } -namespace test1 { +namespace Test1 { struct A { enum Kind { Foo } Kind; A() : Kind(Foo) {} }; } + +namespace Test2 { + +struct A { + A(const A&); +}; + +struct B : virtual A { }; +struct C : A, B { }; + +C f(C c) { + return c; +} + +}