Hi Richard, This commit started causing the attached reduced test case to assert, could you take a look ?
$ clang -cc1 -std=c++11 test.cpp Assertion failed: ((data().DefaultedMoveConstructorIsDeleted || needsOverloadResolutionForMoveConstructor()) && "move constructor should not be deleted"), function setImplicitMoveConstructorIsDeleted, file src/tools/clang/include/clang/AST/DeclCXX.h, line 874.
test.cpp
Description: Binary data
On Nov 3, 2013, at 5:48 PM, Richard Smith <[email protected]> wrote: > Author: rsmith > Date: Sun Nov 3 19:48:18 2013 > New Revision: 193969 > > URL: http://llvm.org/viewvc/llvm-project?rev=193969&view=rev > Log: > Implement final resolution of DR1402: implicitly-declared move operators that > would be deleted are still declared, but are ignored by overload resolution. > > Also, don't delete such members if a subobject has no corresponding move > operation and a non-trivial copy. This causes us to implicitly declare move > operations in more cases, but risks move-assigning virtual bases multiple > times in some circumstances (a warning for that is to follow). > > Modified: > cfe/trunk/include/clang/AST/DeclCXX.h > cfe/trunk/lib/AST/ASTImporter.cpp > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaOverload.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp > cfe/trunk/test/CXX/drs/dr1xx.cpp > cfe/trunk/test/CXX/special/class.copy/implicit-move.cpp > cfe/trunk/test/CXX/special/class.copy/p12-0x.cpp > cfe/trunk/test/CXX/special/class.copy/p23-cxx11.cpp > > Modified: cfe/trunk/include/clang/AST/DeclCXX.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclCXX.h (original) > +++ cfe/trunk/include/clang/AST/DeclCXX.h Sun Nov 3 19:48:18 2013 > @@ -444,14 +444,6 @@ class CXXRecordDecl : public RecordDecl > /// const-qualified reference parameter or a non-reference parameter. > bool HasDeclaredCopyAssignmentWithConstParam : 1; > > - /// \brief Whether an implicit move constructor was attempted to be > declared > - /// but would have been deleted. > - bool FailedImplicitMoveConstructor : 1; > - > - /// \brief Whether an implicit move assignment operator was attempted to > be > - /// declared but would have been deleted. > - bool FailedImplicitMoveAssignment : 1; > - > /// \brief Whether this class describes a C++ lambda. > bool IsLambda : 1; > > @@ -773,12 +765,14 @@ public: > /// \brief \c true if we know for sure that this class has a single, > /// accessible, unambiguous move constructor that is not deleted. > bool hasSimpleMoveConstructor() const { > - return !hasUserDeclaredMoveConstructor() && hasMoveConstructor(); > + return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() && > + !data().DefaultedMoveConstructorIsDeleted; > } > /// \brief \c true if we know for sure that this class has a single, > /// accessible, unambiguous move assignment operator that is not deleted. > bool hasSimpleMoveAssignment() const { > - return !hasUserDeclaredMoveAssignment() && hasMoveAssignment(); > + return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() && > + !data().DefaultedMoveAssignmentIsDeleted; > } > /// \brief \c true if we know for sure that this class has an accessible > /// destructor that is not deleted. > @@ -870,28 +864,23 @@ public: > needsImplicitMoveConstructor(); > } > > - /// \brief Determine whether implicit move constructor generation for this > - /// class has failed before. > - bool hasFailedImplicitMoveConstructor() const { > - return data().FailedImplicitMoveConstructor; > - } > - > - /// \brief Set whether implicit move constructor generation for this class > - /// has failed before. > - void setFailedImplicitMoveConstructor(bool Failed = true) { > - data().FailedImplicitMoveConstructor = Failed; > + /// \brief Set that we attempted to declare an implicitly move > + /// constructor, but overload resolution failed so we deleted it. > + void setImplicitMoveConstructorIsDeleted() { > + assert((data().DefaultedMoveConstructorIsDeleted || > + needsOverloadResolutionForMoveConstructor()) && > + "move constructor should not be deleted"); > + data().DefaultedMoveConstructorIsDeleted = true; > } > > /// \brief Determine whether this class should get an implicit move > /// constructor or if any existing special member function inhibits this. > bool needsImplicitMoveConstructor() const { > - return !hasFailedImplicitMoveConstructor() && > - !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && > + return !(data().DeclaredSpecialMembers & SMF_MoveConstructor) && > !hasUserDeclaredCopyConstructor() && > !hasUserDeclaredCopyAssignment() && > !hasUserDeclaredMoveAssignment() && > - !hasUserDeclaredDestructor() && > - !data().DefaultedMoveConstructorIsDeleted; > + !hasUserDeclaredDestructor(); > } > > /// \brief Determine whether we need to eagerly declare a defaulted move > @@ -947,29 +936,24 @@ public: > needsImplicitMoveAssignment(); > } > > - /// \brief Determine whether implicit move assignment generation for this > - /// class has failed before. > - bool hasFailedImplicitMoveAssignment() const { > - return data().FailedImplicitMoveAssignment; > - } > - > - /// \brief Set whether implicit move assignment generation for this class > - /// has failed before. > - void setFailedImplicitMoveAssignment(bool Failed = true) { > - data().FailedImplicitMoveAssignment = Failed; > + /// \brief Set that we attempted to declare an implicit move assignment > + /// operator, but overload resolution failed so we deleted it. > + void setImplicitMoveAssignmentIsDeleted() { > + assert((data().DefaultedMoveAssignmentIsDeleted || > + needsOverloadResolutionForMoveAssignment()) && > + "move assignment should not be deleted"); > + data().DefaultedMoveAssignmentIsDeleted = true; > } > > /// \brief Determine whether this class should get an implicit move > /// assignment operator or if any existing special member function inhibits > /// this. > bool needsImplicitMoveAssignment() const { > - return !hasFailedImplicitMoveAssignment() && > - !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && > + return !(data().DeclaredSpecialMembers & SMF_MoveAssignment) && > !hasUserDeclaredCopyConstructor() && > !hasUserDeclaredCopyAssignment() && > !hasUserDeclaredMoveConstructor() && > - !hasUserDeclaredDestructor() && > - !data().DefaultedMoveAssignmentIsDeleted; > + !hasUserDeclaredDestructor(); > } > > /// \brief Determine whether we need to eagerly declare a move assignment > > Modified: cfe/trunk/lib/AST/ASTImporter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTImporter.cpp (original) > +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Nov 3 19:48:18 2013 > @@ -1983,9 +1983,6 @@ bool ASTNodeImporter::ImportDefinition(R > = FromData.HasDeclaredCopyConstructorWithConstParam; > ToData.HasDeclaredCopyAssignmentWithConstParam > = FromData.HasDeclaredCopyAssignmentWithConstParam; > - ToData.FailedImplicitMoveConstructor > - = FromData.FailedImplicitMoveConstructor; > - ToData.FailedImplicitMoveAssignment = > FromData.FailedImplicitMoveAssignment; > ToData.IsLambda = FromData.IsLambda; > > SmallVector<CXXBaseSpecifier *, 4> Bases; > > Modified: cfe/trunk/lib/AST/DeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclCXX.cpp (original) > +++ cfe/trunk/lib/AST/DeclCXX.cpp Sun Nov 3 19:48:18 2013 > @@ -71,7 +71,6 @@ CXXRecordDecl::DefinitionData::Definitio > ImplicitCopyAssignmentHasConstParam(true), > HasDeclaredCopyConstructorWithConstParam(false), > HasDeclaredCopyAssignmentWithConstParam(false), > - FailedImplicitMoveConstructor(false), > FailedImplicitMoveAssignment(false), > IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(), > Definition(D), FirstFriend() { > } > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Nov 3 19:48:18 2013 > @@ -9231,11 +9231,6 @@ CXXMethodDecl *Sema::DeclareImplicitCopy > ? SpecialMemberIsTrivial(CopyAssignment, CXXCopyAssignment) > : ClassDecl->hasTrivialCopyAssignment()); > > - // C++11 [class.copy]p19: > - // .... If the class definition does not explicitly declare a copy > - // assignment operator, there is no user-declared move constructor, and > - // there is no user-declared move assignment operator, a copy assignment > - // operator is implicitly declared as defaulted. > if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) > SetDeclDeleted(CopyAssignment, ClassLoc); > > @@ -9572,120 +9567,13 @@ Sema::ComputeDefaultedMoveAssignmentExce > return ExceptSpec; > } > > -/// Determine whether the class type has any direct or indirect virtual base > -/// classes which have a non-trivial move assignment operator. > -static bool > -hasVirtualBaseWithNonTrivialMoveAssignment(Sema &S, CXXRecordDecl > *ClassDecl) { > - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), > - BaseEnd = ClassDecl->vbases_end(); > - Base != BaseEnd; ++Base) { > - CXXRecordDecl *BaseClass = > - cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); > - > - // Try to declare the move assignment. If it would be deleted, then the > - // class does not have a non-trivial move assignment. > - if (BaseClass->needsImplicitMoveAssignment()) > - S.DeclareImplicitMoveAssignment(BaseClass); > - > - if (BaseClass->hasNonTrivialMoveAssignment()) > - return true; > - } > - > - return false; > -} > - > -/// Determine whether the given type either has a move constructor or is > -/// trivially copyable. > -static bool > -hasMoveOrIsTriviallyCopyable(Sema &S, QualType Type, bool IsConstructor) { > - Type = S.Context.getBaseElementType(Type); > - > - // FIXME: Technically, non-trivially-copyable non-class types, such as > - // reference types, are supposed to return false here, but that appears > - // to be a standard defect. > - CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl(); > - if (!ClassDecl || !ClassDecl->getDefinition() || > ClassDecl->isInvalidDecl()) > - return true; > - > - if (Type.isTriviallyCopyableType(S.Context)) > - return true; > - > - if (IsConstructor) { > - // FIXME: Need this because otherwise hasMoveConstructor isn't > guaranteed to > - // give the right answer. > - if (ClassDecl->needsImplicitMoveConstructor()) > - S.DeclareImplicitMoveConstructor(ClassDecl); > - return ClassDecl->hasMoveConstructor(); > - } > - > - // FIXME: Need this because otherwise hasMoveAssignment isn't guaranteed to > - // give the right answer. > - if (ClassDecl->needsImplicitMoveAssignment()) > - S.DeclareImplicitMoveAssignment(ClassDecl); > - return ClassDecl->hasMoveAssignment(); > -} > - > -/// Determine whether all non-static data members and direct or virtual bases > -/// of class \p ClassDecl have either a move operation, or are trivially > -/// copyable. > -static bool subobjectsHaveMoveOrTrivialCopy(Sema &S, CXXRecordDecl > *ClassDecl, > - bool IsConstructor) { > - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), > - BaseEnd = ClassDecl->bases_end(); > - Base != BaseEnd; ++Base) { > - if (Base->isVirtual()) > - continue; > - > - if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor)) > - return false; > - } > - > - for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), > - BaseEnd = ClassDecl->vbases_end(); > - Base != BaseEnd; ++Base) { > - if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor)) > - return false; > - } > - > - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), > - FieldEnd = ClassDecl->field_end(); > - Field != FieldEnd; ++Field) { > - if (!hasMoveOrIsTriviallyCopyable(S, Field->getType(), IsConstructor)) > - return false; > - } > - > - return true; > -} > - > CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { > - // C++11 [class.copy]p20: > - // If the definition of a class X does not explicitly declare a move > - // assignment operator, one will be implicitly declared as defaulted > - // if and only if: > - // > - // - [first 4 bullets] > assert(ClassDecl->needsImplicitMoveAssignment()); > > DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment); > if (DSM.isAlreadyBeingDeclared()) > return 0; > > - // [Checked after we build the declaration] > - // - the move assignment operator would not be implicitly defined as > - // deleted, > - > - // [DR1402]: > - // - X has no direct or indirect virtual base class with a non-trivial > - // move assignment operator, and > - // - each of X's non-static data members and direct or virtual base > classes > - // has a type that either has a move assignment operator or is > trivially > - // copyable. > - if (hasVirtualBaseWithNonTrivialMoveAssignment(*this, ClassDecl) || > - !subobjectsHaveMoveOrTrivialCopy(*this, > ClassDecl,/*Constructor*/false)) { > - ClassDecl->setFailedImplicitMoveAssignment(); > - return 0; > - } > - > // Note: The following rules are largely analoguous to the move > // constructor rules. > > @@ -9729,18 +9617,9 @@ CXXMethodDecl *Sema::DeclareImplicitMove > ? SpecialMemberIsTrivial(MoveAssignment, CXXMoveAssignment) > : ClassDecl->hasTrivialMoveAssignment()); > > - // C++0x [class.copy]p9: > - // If the definition of a class X does not explicitly declare a move > - // assignment operator, one will be implicitly declared as defaulted if > and > - // only if: > - // [...] > - // - the move assignment operator would not be implicitly defined as > - // deleted. > if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) { > - // Cache this result so that we don't try to generate this over and over > - // on every lookup, leaking memory and wasting time. > - ClassDecl->setFailedImplicitMoveAssignment(); > - return 0; > + ClassDecl->setImplicitMoveAssignmentIsDeleted(); > + SetDeclDeleted(MoveAssignment, ClassLoc); > } > > // Note that we have added this copy-assignment operator. > @@ -9782,6 +9661,17 @@ void Sema::DefineImplicitMoveAssignment( > // are assigned, in the order in which they were declared in the class > // definition. > > + // FIXME: Issue a warning if our implicit move assignment operator will > move > + // from a virtual base more than once. For instance, given: > + // > + // struct A { A &operator=(A&&); }; > + // struct B : virtual A {}; > + // struct C : virtual A {}; > + // struct D : B, C {}; > + // > + // If the move assignment operator of D is synthesized, we should warn, > + // because the A vbase will be moved from multiple times. > + > // The statements that form the synthesized function body. > SmallVector<Stmt*, 8> Statements; > > @@ -10071,11 +9961,6 @@ CXXConstructorDecl *Sema::DeclareImplici > ? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor) > : ClassDecl->hasTrivialCopyConstructor()); > > - // C++11 [class.copy]p8: > - // ... If the class definition does not explicitly declare a copy > - // constructor, there is no user-declared move constructor, and there is > no > - // user-declared move assignment operator, a copy constructor is > implicitly > - // declared as defaulted. > if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) > SetDeclDeleted(CopyConstructor, ClassLoc); > > @@ -10195,29 +10080,12 @@ Sema::ComputeDefaultedMoveCtorExceptionS > > CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( > CXXRecordDecl *ClassDecl) > { > - // C++11 [class.copy]p9: > - // If the definition of a class X does not explicitly declare a move > - // constructor, one will be implicitly declared as defaulted if and only > if: > - // > - // - [first 4 bullets] > assert(ClassDecl->needsImplicitMoveConstructor()); > > DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveConstructor); > if (DSM.isAlreadyBeingDeclared()) > return 0; > > - // [Checked after we build the declaration] > - // - the move assignment operator would not be implicitly defined as > - // deleted, > - > - // [DR1402]: > - // - each of X's non-static data members and direct or virtual base > classes > - // has a type that either has a move constructor or is trivially > copyable. > - if (!subobjectsHaveMoveOrTrivialCopy(*this, ClassDecl, > /*Constructor*/true)) { > - ClassDecl->setFailedImplicitMoveConstructor(); > - return 0; > - } > - > QualType ClassType = Context.getTypeDeclType(ClassDecl); > QualType ArgType = Context.getRValueReferenceType(ClassType); > > @@ -10260,16 +10128,9 @@ CXXConstructorDecl *Sema::DeclareImplici > ? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor) > : ClassDecl->hasTrivialMoveConstructor()); > > - // C++0x [class.copy]p9: > - // If the definition of a class X does not explicitly declare a move > - // constructor, one will be implicitly declared as defaulted if and only > if: > - // [...] > - // - the move constructor would not be implicitly defined as deleted. > if (ShouldDeleteSpecialMember(MoveConstructor, CXXMoveConstructor)) { > - // Cache this result so that we don't try to generate this over and over > - // on every lookup, leaking memory and wasting time. > - ClassDecl->setFailedImplicitMoveConstructor(); > - return 0; > + ClassDecl->setImplicitMoveConstructorIsDeleted(); > + SetDeclDeleted(MoveConstructor, ClassLoc); > } > > // Note that we have declared this constructor. > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun Nov 3 19:48:18 2013 > @@ -3602,8 +3602,8 @@ static bool evaluateTypeTrait(Sema &S, T > // is_trivially_constructible is defined as: > // > // is_constructible<T, Args...>::value is true and the variable > - // definition for is_constructible, as defined below, is known to > call no > - // operation that is not trivial. > + // definition for is_constructible, as defined below, is known to > call > + // no operation that is not trivial. > // > // The predicate condition for a template specialization > // is_constructible<T, Args...> shall be satisfied if and only if the > > Modified: cfe/trunk/lib/Sema/SemaOverload.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Nov 3 19:48:18 2013 > @@ -5448,10 +5448,18 @@ Sema::AddOverloadCandidate(FunctionDecl > if (!CandidateSet.isNewCandidate(Function)) > return; > > + // C++11 [class.copy]p11: [DR1402] > + // A defaulted move constructor that is defined as deleted is ignored by > + // overload resolution. > + CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function); > + if (Constructor && Constructor->isDefaulted() && Constructor->isDeleted() > && > + Constructor->isMoveConstructor()) > + return; > + > // Overload resolution is always an unevaluated context. > EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); > > - if (CXXConstructorDecl *Constructor = > dyn_cast<CXXConstructorDecl>(Function)){ > + if (Constructor) { > // C++ [class.copy]p3: > // A member function template is never instantiated to perform the copy > // of a class object to an object of its class type. > @@ -5626,6 +5634,13 @@ Sema::AddMethodCandidate(CXXMethodDecl * > if (!CandidateSet.isNewCandidate(Method)) > return; > > + // C++11 [class.copy]p23: [DR1402] > + // A defaulted move assignment operator that is defined as deleted is > + // ignored by overload resolution. > + if (Method->isDefaulted() && Method->isDeleted() && > + Method->isMoveAssignmentOperator()) > + return; > + > // Overload resolution is always an unevaluated context. > EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); > > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Nov 3 19:48:18 2013 > @@ -1208,8 +1208,6 @@ void ASTDeclReader::ReadCXXDefinitionDat > Data.ImplicitCopyAssignmentHasConstParam = Record[Idx++]; > Data.HasDeclaredCopyConstructorWithConstParam = Record[Idx++]; > Data.HasDeclaredCopyAssignmentWithConstParam = Record[Idx++]; > - Data.FailedImplicitMoveConstructor = Record[Idx++]; > - Data.FailedImplicitMoveAssignment = Record[Idx++]; > > Data.NumBases = Record[Idx++]; > if (Data.NumBases) > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Nov 3 19:48:18 2013 > @@ -5106,8 +5106,6 @@ void ASTWriter::AddCXXDefinitionData(con > Record.push_back(Data.ImplicitCopyAssignmentHasConstParam); > Record.push_back(Data.HasDeclaredCopyConstructorWithConstParam); > Record.push_back(Data.HasDeclaredCopyAssignmentWithConstParam); > - Record.push_back(Data.FailedImplicitMoveConstructor); > - Record.push_back(Data.FailedImplicitMoveAssignment); > // IsLambda bit is already saved. > > Record.push_back(Data.NumBases); > > Modified: cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp (original) > +++ cfe/trunk/test/CXX/class.derived/class.abstract/p16.cpp Sun Nov 3 > 19:48:18 2013 > @@ -22,7 +22,7 @@ struct H; > struct D { > virtual E &operator=(const E &); // expected-note {{here}} > virtual F &operator=(const F &); > - virtual G &operator=(G&&); > + virtual G &operator=(G&&); // expected-note {{here}} > virtual H &operator=(H&&); // expected-note {{here}} > friend struct F; > > @@ -34,8 +34,8 @@ private: > struct E : D {}; // expected-error {{deleted function '~E' cannot override a > non-deleted function}} \ > // expected-error {{deleted function 'operator=' cannot > override a non-deleted function}} > struct F : D {}; > -// No move ctor here, because it would be deleted. > struct G : D {}; // expected-error {{deleted function '~G' cannot override a > non-deleted function}} > + // expected-error@-1 {{deleted function 'operator=' cannot > override a non-deleted function}} > struct H : D { > H &operator=(H&&) = default; // expected-error {{deleted function > 'operator=' cannot override a non-deleted function}} > ~H(); > > Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/drs/dr1xx.cpp (original) > +++ cfe/trunk/test/CXX/drs/dr1xx.cpp Sun Nov 3 19:48:18 2013 > @@ -71,7 +71,7 @@ namespace dr109 { // dr109: yes > > namespace dr111 { // dr111: dup 535 > struct A { A(); A(volatile A&, int = 0); A(A&, const char * = "foo"); }; > - struct B : A { B(); }; // expected-note {{would lose const qualifier}} > expected-note {{requires 0 arguments}} > + struct B : A { B(); }; // expected-note +{{would lose const qualifier}} > expected-note {{requires 0 arguments}} > const B b1; > B b2(b1); // expected-error {{no matching constructor}} > } > > Modified: cfe/trunk/test/CXX/special/class.copy/implicit-move.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/implicit-move.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/special/class.copy/implicit-move.cpp (original) > +++ cfe/trunk/test/CXX/special/class.copy/implicit-move.cpp Sun Nov 3 > 19:48:18 2013 > @@ -190,49 +190,59 @@ namespace DR1402 { > NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = > default; > }; > > - // A non-movable, non-trivially-copyable class type as a subobject inhibits > - // the declaration of a move operation. > - struct NoMove1 { NonTrivialCopyCtor ntcc; }; // expected-note 2{{'const > DR1402::NoMove1 &'}} > - struct NoMove2 { NonTrivialCopyAssign ntcc; }; // expected-note 2{{'const > DR1402::NoMove2 &'}} > - struct NoMove3 : NonTrivialCopyCtor {}; // expected-note 2{{'const > DR1402::NoMove3 &'}} > - struct NoMove4 : NonTrivialCopyAssign {}; // expected-note 2{{'const > DR1402::NoMove4 &'}} > - struct NoMove5 : virtual NonTrivialCopyCtor {}; // expected-note 2{{'const > DR1402::NoMove5 &'}} > - struct NoMove6 : virtual NonTrivialCopyAssign {}; // expected-note > 2{{'const DR1402::NoMove6 &'}} > - struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'const > DR1402::NoMove7 &'}} > - struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'const > DR1402::NoMove8 &'}} > + // DR1402: A non-movable, non-trivially-copyable class type as a subobject > no > + // longer inhibits the declaration of a move operation. > + struct NoMove1 { NonTrivialCopyCtor ntcc; }; > + struct NoMove2 { NonTrivialCopyAssign ntcc; }; > + struct NoMove3 : NonTrivialCopyCtor {}; > + struct NoMove4 : NonTrivialCopyAssign {}; > + struct NoMove5 : virtual NonTrivialCopyCtor {}; > + struct NoMove6 : virtual NonTrivialCopyAssign {}; > + struct NoMove7 : NonTrivialCopyCtorVBase {}; > + struct NoMove8 : NonTrivialCopyAssignVBase {}; > > - // A non-trivially-move-assignable virtual base class inhibits the > declaration > - // of a move assignment (which might move-assign the base class multiple > - // times). > + // DR1402: A non-trivially-move-assignable virtual base class no longer > + // inhibits the declaration of a move assignment (even though it might > + // move-assign the base class multiple times). > struct NoMove9 : NonTrivialMoveAssign {}; > - struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note > {{'const DR1402::NoMove10 &'}} > - struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'const > DR1402::NoMove11 &'}} > + struct NoMove10 : virtual NonTrivialMoveAssign {}; > + struct NoMove11 : NonTrivialMoveAssignVBase {}; > > - struct Test { > - friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{does not match}} > - friend NoMove2::NoMove2(NoMove2 &&); // expected-error {{does not match}} > - friend NoMove3::NoMove3(NoMove3 &&); // expected-error {{does not match}} > - friend NoMove4::NoMove4(NoMove4 &&); // expected-error {{does not match}} > - friend NoMove5::NoMove5(NoMove5 &&); // expected-error {{does not match}} > - friend NoMove6::NoMove6(NoMove6 &&); // expected-error {{does not match}} > - friend NoMove7::NoMove7(NoMove7 &&); // expected-error {{does not match}} > - friend NoMove8::NoMove8(NoMove8 &&); // expected-error {{does not match}} > - friend NoMove9::NoMove9(NoMove9 &&); > - friend NoMove10::NoMove10(NoMove10 &&); > - friend NoMove11::NoMove11(NoMove11 &&); > + template<typename T> void test(T t) { > + (void)T(static_cast<T&&>(t)); // ok > + t = static_cast<T&&>(t); // ok > + } > + template void test(NoMove1); > + template void test(NoMove2); > + template void test(NoMove3); > + template void test(NoMove4); > + template void test(NoMove5); > + template void test(NoMove6); > + template void test(NoMove7); > + template void test(NoMove8); > + template void test(NoMove9); > + template void test(NoMove10); > + template void test(NoMove11); > > - friend NoMove1 &NoMove1::operator=(NoMove1 &&); // expected-error {{does > not match}} > - friend NoMove2 &NoMove2::operator=(NoMove2 &&); // expected-error {{does > not match}} > - friend NoMove3 &NoMove3::operator=(NoMove3 &&); // expected-error {{does > not match}} > - friend NoMove4 &NoMove4::operator=(NoMove4 &&); // expected-error {{does > not match}} > - friend NoMove5 &NoMove5::operator=(NoMove5 &&); // expected-error {{does > not match}} > - friend NoMove6 &NoMove6::operator=(NoMove6 &&); // expected-error {{does > not match}} > - friend NoMove7 &NoMove7::operator=(NoMove7 &&); // expected-error {{does > not match}} > - friend NoMove8 &NoMove8::operator=(NoMove8 &&); // expected-error {{does > not match}} > - friend NoMove9 &NoMove9::operator=(NoMove9 &&); > - friend NoMove10 &NoMove10::operator=(NoMove10 &&); // expected-error > {{does not match}} > - friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error > {{does not match}} > + struct CopyOnly { > + CopyOnly(const CopyOnly&); > + CopyOnly &operator=(const CopyOnly&); > }; > + struct MoveOnly { > + MoveOnly(MoveOnly&&); // expected-note {{user-declared move}} > + MoveOnly &operator=(MoveOnly&&); > + }; > + template void test(CopyOnly); // ok, copies > + template void test(MoveOnly); // ok, moves > + struct CopyAndMove { // expected-note {{implicitly deleted}} > + CopyOnly co; > + MoveOnly mo; // expected-note {{deleted copy}} > + }; > + template void test(CopyAndMove); // ok, copies co, moves mo > + void test2(CopyAndMove cm) { > + (void)CopyAndMove(cm); // expected-error {{deleted}} > + cm = cm; // expected-error {{deleted}} > + } > } > > namespace PR12625 { > > Modified: cfe/trunk/test/CXX/special/class.copy/p12-0x.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p12-0x.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/special/class.copy/p12-0x.cpp (original) > +++ cfe/trunk/test/CXX/special/class.copy/p12-0x.cpp Sun Nov 3 19:48:18 2013 > @@ -157,8 +157,8 @@ namespace TrivialityDependsOnImplicitDel > > struct NoAccess { > PrivateMove pm; > - // NoAccess's move would be deleted, so is suppressed, > - // so moves of it use PrivateMove's copy ctor, which is trivial. > + // NoAccess's move is deleted, so moves of it use PrivateMove's copy > ctor, > + // which is trivial. > }; > static_assert(__is_trivially_constructible(NoAccess, const NoAccess &), ""); > static_assert(__is_trivially_constructible(NoAccess, NoAccess &&), ""); > > Modified: cfe/trunk/test/CXX/special/class.copy/p23-cxx11.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.copy/p23-cxx11.cpp?rev=193969&r1=193968&r2=193969&view=diff > ============================================================================== > --- cfe/trunk/test/CXX/special/class.copy/p23-cxx11.cpp (original) > +++ cfe/trunk/test/CXX/special/class.copy/p23-cxx11.cpp Sun Nov 3 19:48:18 > 2013 > @@ -9,7 +9,15 @@ template<typename T> struct CopyAssign { > template<typename T> struct MoveAssign { > static T t; > void test() { > - t = static_cast<T&&>(t); // expected-error +{{deleted}} > + // Overload resolution will ignore a defaulted, deleted move assignment, > + // so check for it in a different way. > + T &(T::*f)(T&&) = &T::operator=; // expected-error +{{deleted}} > + } > +}; > +template<typename T> struct MoveOrCopyAssign { > + static T t; > + void test() { > + t = static_cast<T&&>(t); // expected-error +{{copy assignment operator > is implicitly deleted}} > } > }; > > @@ -89,29 +97,32 @@ struct D1 { > AmbiguousCopyAssign a; // expected-note {{field 'a' has multiple copy}} > }; > struct D2 { > - D2 &operator=(D2 &&) = default; // expected-note {{here}} > + D2 &operator=(D2 &&) = default; // expected-note {{here}} expected-note > {{copy assignment operator is implicitly deleted}} > AmbiguousMoveAssign a; // expected-note {{field 'a' has multiple move}} > }; > struct D3 { > DeletedCopyAssign a; // expected-note {{field 'a' has a deleted copy}} > }; > struct D4 { > - D4 &operator=(D4 &&) = default; // expected-note {{here}} > + D4 &operator=(D4 &&) = default; // expected-note {{here}} expected-note > {{copy assignment operator is implicitly deleted}} > DeletedMoveAssign a; // expected-note {{field 'a' has a deleted move}} > }; > struct D5 { > InaccessibleCopyAssign a; // expected-note {{field 'a' has an inaccessible > copy}} > }; > struct D6 { > - D6 &operator=(D6 &&) = default; // expected-note {{here}} > + D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note > {{copy assignment operator is implicitly deleted}} > InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible > move}} > }; > template struct CopyAssign<D1>; // expected-note {{here}} > template struct MoveAssign<D2>; // expected-note {{here}} > +template struct MoveOrCopyAssign<D2>; // expected-note {{here}} > template struct CopyAssign<D3>; // expected-note {{here}} > template struct MoveAssign<D4>; // expected-note {{here}} > +template struct MoveOrCopyAssign<D4>; // expected-note {{here}} > template struct CopyAssign<D5>; // expected-note {{here}} > template struct MoveAssign<D6>; // expected-note {{here}} > +template struct MoveOrCopyAssign<D6>; // expected-note {{here}} > > // -- a direct or virtual base that cannot be copied/moved > struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class > 'AmbiguousCopyAssign' has multiple copy}} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
