Author: Richard Smith Date: 2020-06-04T19:19:01-07:00 New Revision: c57f8a3a20540fcf9fbf98c0a73f381ec32fce2a
URL: https://github.com/llvm/llvm-project/commit/c57f8a3a20540fcf9fbf98c0a73f381ec32fce2a DIFF: https://github.com/llvm/llvm-project/commit/c57f8a3a20540fcf9fbf98c0a73f381ec32fce2a.diff LOG: PR46209: properly determine whether a copy assignment operator is trivial. We previously took a shortcut by assuming that if a subobject had a trivial copy assignment operator (with a few side-conditions), we would always invoke it, and could avoid going through overload resolution. That turns out to not be correct in the presenve of ref-qualifiers (and also won't be the case for copy-assignments with requires-clauses either). Use the same logic for lazy declaration of copy-assignments that we use for all other special member functions. Added: Modified: clang/include/clang/AST/CXXRecordDeclDefinitionBits.def clang/include/clang/AST/DeclCXX.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/DeclCXX.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/test/AST/ast-dump-decl-context-json.cpp clang/test/AST/ast-dump-decl.cpp clang/test/AST/ast-dump-expr-json.cpp clang/test/AST/ast-dump-record-definition-data-json.cpp clang/test/AST/ast-dump-records-json.cpp clang/test/AST/ast-dump-records.cpp clang/test/AST/ast-dump-special-member-functions.cpp clang/test/AST/ast-dump-template-decls-json.cpp clang/test/SemaCXX/type-traits.cpp clang/test/SemaObjCXX/arc-0x.mm clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index bd4d8247aeca..33e65f8ebf44 100644 --- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -140,6 +140,7 @@ FIELD(HasInheritedAssignment, 1, NO_MERGE) /// @{ FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE) +FIELD(NeedOverloadResolutionForCopyAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @} @@ -149,6 +150,7 @@ FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @{ FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE) +FIELD(DefaultedCopyAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE) /// @} diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 856717fa0abb..2b8d7e879a0a 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -712,6 +712,13 @@ class CXXRecordDecl : public RecordDecl { !data().DefaultedMoveConstructorIsDeleted; } + /// \c true if we know for sure that this class has a single, + /// accessible, unambiguous copy assignment operator that is not deleted. + bool hasSimpleCopyAssignment() const { + return !hasUserDeclaredCopyAssignment() && + !data().DefaultedCopyAssignmentIsDeleted; + } + /// \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 { @@ -872,6 +879,15 @@ class CXXRecordDecl : public RecordDecl { return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } + /// Set that we attempted to declare an implicit copy assignment + /// operator, but overload resolution failed so we deleted it. + void setImplicitCopyAssignmentIsDeleted() { + assert((data().DefaultedCopyAssignmentIsDeleted || + needsOverloadResolutionForCopyAssignment()) && + "copy assignment should not be deleted"); + data().DefaultedCopyAssignmentIsDeleted = true; + } + /// Determine whether this class needs an implicit copy /// assignment operator to be lazily declared. bool needsImplicitCopyAssignment() const { @@ -881,7 +897,16 @@ class CXXRecordDecl : public RecordDecl { /// Determine whether we need to eagerly declare a defaulted copy /// assignment operator for this class. bool needsOverloadResolutionForCopyAssignment() const { - return data().HasMutableFields; + // C++20 [class.copy.assign]p2: + // If the class definition declares a move constructor or move assignment + // operator, the implicitly declared copy assignment operator is defined + // as deleted. + // In MSVC mode, sometimes a declared move constructor does not delete an + // implicit copy assignment, so defer this choice to Sema. + if (data().UserDeclaredSpecialMembers & + (SMF_MoveConstructor | SMF_MoveAssignment)) + return true; + return data().NeedOverloadResolutionForCopyAssignment; } /// Determine whether an implicit copy assignment operator for this diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index a2a712e6b6ca..8b96e20e374d 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2795,7 +2795,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { return CDeclOrErr.takeError(); D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr, DCXX->hasKnownLambdaInternalLinkage()); - } else if (DCXX->isInjectedClassName()) { + } else if (DCXX->isInjectedClassName()) { // We have to be careful to do a similar dance to the one in // Sema::ActOnStartCXXMemberDeclarations const bool DelayTypeCreation = true; diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 4d184b5a4703..6f1fd2f14ede 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -84,10 +84,12 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) HasInheritedConstructor(false), HasInheritedAssignment(false), NeedOverloadResolutionForCopyConstructor(false), NeedOverloadResolutionForMoveConstructor(false), + NeedOverloadResolutionForCopyAssignment(false), NeedOverloadResolutionForMoveAssignment(false), NeedOverloadResolutionForDestructor(false), DefaultedCopyConstructorIsDeleted(false), DefaultedMoveConstructorIsDeleted(false), + DefaultedCopyAssignmentIsDeleted(false), DefaultedMoveAssignmentIsDeleted(false), DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), HasTrivialSpecialMembersForCall(SMF_All), @@ -435,10 +437,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); // Keep track of the presence of mutable fields. - if (BaseClassDecl->hasMutableFields()) { + if (BaseClassDecl->hasMutableFields()) data().HasMutableFields = true; - data().NeedOverloadResolutionForCopyConstructor = true; - } if (BaseClassDecl->hasUninitializedReferenceMember()) data().HasUninitializedReferenceMember = true; @@ -511,6 +511,8 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { // -- a direct or virtual base class B that cannot be copied/moved [...] // -- a non-static data member of class type M (or array thereof) // that cannot be copied or moved [...] + if (!Subobj->hasSimpleCopyAssignment()) + data().NeedOverloadResolutionForCopyAssignment = true; if (!Subobj->hasSimpleMoveAssignment()) data().NeedOverloadResolutionForMoveAssignment = true; @@ -978,10 +980,8 @@ void CXXRecordDecl::addedMember(Decl *D) { } // Keep track of the presence of mutable fields. - if (Field->isMutable()) { + if (Field->isMutable()) data().HasMutableFields = true; - data().NeedOverloadResolutionForCopyConstructor = true; - } // C++11 [class.union]p8, DR1460: // If X is a union, a non-static data member of X that is not an anonymous @@ -1025,10 +1025,12 @@ void CXXRecordDecl::addedMember(Decl *D) { if (isUnion()) { data().DefaultedCopyConstructorIsDeleted = true; data().DefaultedMoveConstructorIsDeleted = true; + data().DefaultedCopyAssignmentIsDeleted = true; data().DefaultedMoveAssignmentIsDeleted = true; data().DefaultedDestructorIsDeleted = true; data().NeedOverloadResolutionForCopyConstructor = true; data().NeedOverloadResolutionForMoveConstructor = true; + data().NeedOverloadResolutionForCopyAssignment = true; data().NeedOverloadResolutionForMoveAssignment = true; data().NeedOverloadResolutionForDestructor = true; } @@ -1095,8 +1097,10 @@ void CXXRecordDecl::addedMember(Decl *D) { // A defaulted copy/move assignment operator for a class X is defined // as deleted if X has: // -- a non-static data member of reference type - if (T->isReferenceType()) + if (T->isReferenceType()) { + data().DefaultedCopyAssignmentIsDeleted = true; data().DefaultedMoveAssignmentIsDeleted = true; + } // Bitfields of length 0 are also zero-sized, but we already bailed out for // those because they are always unnamed. @@ -1115,6 +1119,7 @@ void CXXRecordDecl::addedMember(Decl *D) { // parameter. data().NeedOverloadResolutionForCopyConstructor = true; data().NeedOverloadResolutionForMoveConstructor = true; + data().NeedOverloadResolutionForCopyAssignment = true; data().NeedOverloadResolutionForMoveAssignment = true; } @@ -1128,6 +1133,8 @@ void CXXRecordDecl::addedMember(Decl *D) { data().DefaultedCopyConstructorIsDeleted = true; if (FieldRec->hasNonTrivialMoveConstructor()) data().DefaultedMoveConstructorIsDeleted = true; + if (FieldRec->hasNonTrivialCopyAssignment()) + data().DefaultedCopyAssignmentIsDeleted = true; if (FieldRec->hasNonTrivialMoveAssignment()) data().DefaultedMoveAssignmentIsDeleted = true; if (FieldRec->hasNonTrivialDestructor()) @@ -1141,6 +1148,8 @@ void CXXRecordDecl::addedMember(Decl *D) { FieldRec->data().NeedOverloadResolutionForCopyConstructor; data().NeedOverloadResolutionForMoveConstructor |= FieldRec->data().NeedOverloadResolutionForMoveConstructor; + data().NeedOverloadResolutionForCopyAssignment |= + FieldRec->data().NeedOverloadResolutionForCopyAssignment; data().NeedOverloadResolutionForMoveAssignment |= FieldRec->data().NeedOverloadResolutionForMoveAssignment; data().NeedOverloadResolutionForDestructor |= @@ -1238,9 +1247,15 @@ void CXXRecordDecl::addedMember(Decl *D) { } // Keep track of the presence of mutable fields. - if (FieldRec->hasMutableFields()) { + if (FieldRec->hasMutableFields()) data().HasMutableFields = true; + + if (Field->isMutable()) { + // Our copy constructor/assignment might call something other than + // the subobject's copy constructor/assignment if it's mutable and of + // class type. data().NeedOverloadResolutionForCopyConstructor = true; + data().NeedOverloadResolutionForCopyAssignment = true; } // C++11 [class.copy]p13: @@ -1296,8 +1311,10 @@ void CXXRecordDecl::addedMember(Decl *D) { // as deleted if X has: // -- a non-static data member of const non-class type (or array // thereof) - if (T.isConstQualified()) + if (T.isConstQualified()) { + data().DefaultedCopyAssignmentIsDeleted = true; data().DefaultedMoveAssignmentIsDeleted = true; + } } // C++14 [meta.unary.prop]p4: @@ -1382,6 +1399,9 @@ void CXXRecordDecl::setCaptures(ArrayRef<LambdaCapture> Captures) { *ToCapture++ = Captures[I]; } + + if (!lambdaIsDefaultConstructibleAndAssignable()) + Data.DefaultedCopyAssignmentIsDeleted = true; } void CXXRecordDecl::setTrivialForCallFlags(CXXMethodDecl *D) { diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 8edfed673ce2..2f7aab050b76 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -386,6 +386,7 @@ static llvm::json::Object createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) { llvm::json::Object Ret; + FIELD2("simple", hasSimpleCopyAssignment); FIELD2("trivial", hasTrivialCopyAssignment); FIELD2("nonTrivial", hasNonTrivialCopyAssignment); FIELD2("hasConstParam", hasCopyAssignmentWithConstParam); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 1e567e2ad958..72f0ba37e3e7 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1663,6 +1663,7 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "CopyAssignment"; } + FLAG(hasSimpleCopyAssignment, simple); FLAG(hasTrivialCopyAssignment, trivial); FLAG(hasNonTrivialCopyAssignment, non_trivial); FLAG(hasCopyAssignmentWithConstParam, has_const_param); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index a137e6c0b745..ed12b6cacdbe 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13789,8 +13789,10 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { Scope *S = getScopeForContext(ClassDecl); CheckImplicitSpecialMemberDeclaration(S, CopyAssignment); - if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) + if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) { + ClassDecl->setImplicitCopyAssignmentIsDeleted(); SetDeclDeleted(CopyAssignment, ClassLoc); + } if (S) PushOnScopeChains(CopyAssignment, S, false); diff --git a/clang/test/AST/ast-dump-decl-context-json.cpp b/clang/test/AST/ast-dump-decl-context-json.cpp index 8c67952ba66f..1d67e26fc80c 100644 --- a/clang/test/AST/ast-dump-decl-context-json.cpp +++ b/clang/test/AST/ast-dump-decl-context-json.cpp @@ -172,6 +172,7 @@ void S::Method() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp index 529733475a25..1199ad7d14d9 100644 --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -79,7 +79,7 @@ namespace testCXXRecordDecl { // CHECK-NEXT: DefaultConstructor exists trivial constexpr // CHECK-NEXT: CopyConstructor simple trivial has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial -// CHECK-NEXT: CopyAssignment trivial has_const_param +// CHECK-NEXT: CopyAssignment simple trivial has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial // CHECK-NEXT: Destructor simple irrelevant trivial @@ -94,7 +94,7 @@ namespace testCXXRecordDecl { // CHECK-NEXT: DefaultConstructor exists non_trivial // CHECK-NEXT: CopyConstructor simple non_trivial has_const_param // CHECK-NEXT: MoveConstructor exists simple non_trivial -// CHECK-NEXT: CopyAssignment non_trivial has_const_param +// CHECK-NEXT: CopyAssignment simple non_trivial has_const_param // CHECK-NEXT: MoveAssignment exists simple non_trivial // CHECK-NEXT: Destructor simple irrelevant trivial // CHECK-NEXT: virtual private 'testCXXRecordDecl::A' @@ -283,7 +283,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor -// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveAssignment // CHECK-NEXT: | | `-Destructor non_trivial user_declared // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit referenced class TestClassTemplate @@ -297,7 +297,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor -// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveAssignment // CHECK-NEXT: | | `-Destructor non_trivial user_declared // CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A' @@ -318,7 +318,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B' @@ -330,7 +330,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment // CHECK-NEXT: | `-Destructor non_trivial user_declared // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C' @@ -346,7 +346,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment // CHECK-NEXT: | `-Destructor non_trivial user_declared // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D' @@ -365,7 +365,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:38, col:44> col:44 implicit class TestClassTemplatePartial @@ -376,7 +376,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0' @@ -399,7 +399,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 implicit struct TestTemplateDefaultType @@ -427,7 +427,7 @@ namespace testClassTemplateDecl { // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit -// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:41, col:48> col:48 implicit struct TestTemplateTemplateDefaultType @@ -466,7 +466,7 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate @@ -479,7 +479,7 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial - // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' @@ -510,7 +510,7 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial - // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A' @@ -534,7 +534,7 @@ namespace testCanonicalTemplate { // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate2 diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp index 09e775e22ecf..403ce670f193 100644 --- a/clang/test/AST/ast-dump-expr-json.cpp +++ b/clang/test/AST/ast-dump-expr-json.cpp @@ -3735,6 +3735,7 @@ void TestNonADLCall3() { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { diff --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp index 44ec2a2f7bc6..6e29085ee7d5 100644 --- a/clang/test/AST/ast-dump-record-definition-data-json.cpp +++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp @@ -417,21 +417,21 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 197, +// CHECK-NEXT: "col": 33, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { // CHECK-NEXT: "offset": 197, // CHECK-NEXT: "col": 33, // CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, // CHECK-NEXT: "name": "auto:1", @@ -533,21 +533,21 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 197, +// CHECK-NEXT: "col": 33, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { // CHECK-NEXT: "offset": 197, // CHECK-NEXT: "col": 33, // CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, // CHECK-NEXT: "name": "auto:1", @@ -608,21 +608,21 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "id": "0x{{.*}}", // CHECK-NEXT: "kind": "TemplateTypeParmDecl", // CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 197, +// CHECK-NEXT: "col": 33, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 193, +// CHECK-NEXT: "col": 29, +// CHECK-NEXT: "tokLen": 4 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { // CHECK-NEXT: "offset": 197, // CHECK-NEXT: "col": 33, // CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 193, -// CHECK-NEXT: "col": 29, -// CHECK-NEXT: "tokLen": 4 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 197, -// CHECK-NEXT: "col": 33, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }, // CHECK-NEXT: "isImplicit": true, // CHECK-NEXT: "name": "auto:1", @@ -750,6 +750,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -891,6 +892,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1032,6 +1034,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1134,6 +1137,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1258,6 +1262,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1382,6 +1387,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1528,6 +1534,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1656,7 +1663,8 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -1922,6 +1930,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2024,6 +2033,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2176,6 +2186,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2422,6 +2433,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2554,6 +2566,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2696,7 +2709,8 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -2962,6 +2976,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3090,7 +3105,8 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -3356,7 +3372,8 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -3622,6 +3639,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3741,6 +3759,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3874,6 +3893,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4018,6 +4038,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4121,6 +4142,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4269,6 +4291,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4412,13 +4435,14 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsOverloadResolution": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsOverloadResolution": true, +// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -4505,119 +4529,6 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "qualType": "int" // CHECK-NEXT: }, // CHECK-NEXT: "mutable": true -// CHECK-NEXT: }, -// CHECK-NEXT: { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "CXXConstructorDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "line": 102, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "name": "HasMutableFields", -// CHECK-NEXT: "mangledName": "_ZN16HasMutableFieldsC1ERKS_", -// CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "void (const HasMutableFields &)" -// CHECK-NEXT: }, -// CHECK-NEXT: "inline": true, -// CHECK-NEXT: "constexpr": true, -// CHECK-NEXT: "explicitlyDefaulted": "default", -// CHECK-NEXT: "inner": [ -// CHECK-NEXT: { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "ParmVarDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "const HasMutableFields &" -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: }, -// CHECK-NEXT: { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "CXXMethodDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "isImplicit": true, -// CHECK-NEXT: "name": "operator=", -// CHECK-NEXT: "mangledName": "_ZN16HasMutableFieldsaSERKS_", -// CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "HasMutableFields &(const HasMutableFields &)" -// CHECK-NEXT: }, -// CHECK-NEXT: "inline": true, -// CHECK-NEXT: "constexpr": true, -// CHECK-NEXT: "explicitlyDefaulted": "default", -// CHECK-NEXT: "inner": [ -// CHECK-NEXT: { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "ParmVarDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 1497, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 16 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "type": { -// CHECK-NEXT: "qualType": "const HasMutableFields &" -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -4652,6 +4563,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4776,6 +4688,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -4872,6 +4785,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -5025,6 +4939,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -5128,6 +5043,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -5277,6 +5193,7 @@ struct DoesNotAllowConstDefaultInit { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { diff --git a/clang/test/AST/ast-dump-records-json.cpp b/clang/test/AST/ast-dump-records-json.cpp index b8395d8ed8ea..9cf2278c4196 100644 --- a/clang/test/AST/ast-dump-records-json.cpp +++ b/clang/test/AST/ast-dump-records-json.cpp @@ -178,6 +178,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -597,6 +598,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -693,6 +695,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -820,6 +823,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1019,6 +1023,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1218,6 +1223,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1443,6 +1449,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1863,6 +1870,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1959,6 +1967,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2086,6 +2095,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2285,6 +2295,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2484,6 +2495,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2724,6 +2736,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2964,6 +2977,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3205,6 +3219,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3316,6 +3331,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -3424,7 +3440,8 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -3662,7 +3679,8 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -3914,7 +3932,8 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "copyAssign": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: "nonTrivial": true, +// CHECK-NEXT: "simple": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, @@ -4153,6 +4172,7 @@ struct Derived6 : virtual public Bases... { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { diff --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp index 3682e1a1a4be..28b9bb496917 100644 --- a/clang/test/AST/ast-dump-records.cpp +++ b/clang/test/AST/ast-dump-records.cpp @@ -12,7 +12,7 @@ struct A { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -44,7 +44,7 @@ struct C { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -55,7 +55,7 @@ struct C { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit int a; @@ -69,7 +69,7 @@ struct C { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit int c; @@ -91,7 +91,7 @@ struct C { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit int e, f; @@ -113,7 +113,7 @@ struct D { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -138,7 +138,7 @@ union E { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -170,7 +170,7 @@ union G { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -181,7 +181,7 @@ union G { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -198,7 +198,7 @@ union G { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit @@ -221,7 +221,7 @@ union G { // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit - // CHECK-NEXT: CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param + // CHECK-NEXT: CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: Destructor simple irrelevant trivial needs_implicit diff --git a/clang/test/AST/ast-dump-special-member-functions.cpp b/clang/test/AST/ast-dump-special-member-functions.cpp index 0b025397fa93..dcfc71f74945 100644 --- a/clang/test/AST/ast-dump-special-member-functions.cpp +++ b/clang/test/AST/ast-dump-special-member-functions.cpp @@ -283,10 +283,14 @@ struct DoesNotNeedImplicitCopyAssignment { DoesNotNeedImplicitCopyAssignment& operator=(const DoesNotNeedImplicitCopyAssignment&) {} }; +struct DeclaresCopyAssignment { + DeclaresCopyAssignment &operator=(const DeclaresCopyAssignment&) &; +}; + struct CopyAssignmentNeedsOverloadResolution { // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct CopyAssignmentNeedsOverloadResolution definition // CHECK: CopyAssignment {{.*}}needs_overload_resolution{{.*}} - mutable int i; + DeclaresCopyAssignment i; }; struct CopyAssignmentDoesNotNeedOverloadResolution { diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp index 5290d482518f..658358c5789e 100644 --- a/clang/test/AST/ast-dump-template-decls-json.cpp +++ b/clang/test/AST/ast-dump-template-decls-json.cpp @@ -1351,6 +1351,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1461,6 +1462,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1643,6 +1645,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1747,6 +1750,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -1939,6 +1943,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2093,6 +2098,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { @@ -2247,6 +2253,7 @@ void V<Ty>::f() {} // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index c2f233b5d0c9..9104bfcb2ea4 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -2789,3 +2789,43 @@ namespace ErrorType { }; bool b = __has_unique_object_representations(T); }; + +namespace PR46209 { + // Foo has both a trivial assignment operator and a non-trivial one. + struct Foo { + Foo &operator=(const Foo &) & { return *this; } + Foo &operator=(const Foo &) && = default; + }; + + // Bar's copy assignment calls Foo's non-trivial assignment. + struct Bar { + Foo foo; + }; + + static_assert(!__is_trivially_assignable(Foo &, const Foo &), ""); + static_assert(!__is_trivially_assignable(Bar &, const Bar &), ""); + + // Foo2 has both a trivial assignment operator and a non-trivial one. + struct Foo2 { + Foo2 &operator=(const Foo2 &) & = default; + Foo2 &operator=(const Foo2 &) && { return *this; } + }; + + // Bar2's copy assignment calls Foo2's trivial assignment. + struct Bar2 { + Foo2 foo; + }; + + static_assert(__is_trivially_assignable(Foo2 &, const Foo2 &), ""); + static_assert(__is_trivially_assignable(Bar2 &, const Bar2 &), ""); +} + +namespace ConstClass { + struct A { + A &operator=(const A&) = default; + }; + struct B { + const A a; + }; + static_assert(!__is_trivially_assignable(B&, const B&), ""); +} diff --git a/clang/test/SemaObjCXX/arc-0x.mm b/clang/test/SemaObjCXX/arc-0x.mm index 7a4fa4432a03..0e80b7baf2a1 100644 --- a/clang/test/SemaObjCXX/arc-0x.mm +++ b/clang/test/SemaObjCXX/arc-0x.mm @@ -161,7 +161,7 @@ void test() { struct S1 { union { - union { // expected-note 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} expected-note 5 {{'S1' is implicitly deleted because field '' has a deleted}} + union { // expected-note 7 {{'S1' is implicitly deleted because field '' has a deleted}} id f0; // expected-note 3 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}} char f1; }; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index fa5c61eece29..0070c22164a6 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -1330,33 +1330,30 @@ TEST(Matcher, MatchesPureMethod) { } TEST(Matcher, MatchesCopyAssignmentOperator) { - EXPECT_TRUE(matches("class X { X &operator=(X); };", - cxxMethodDecl(isCopyAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(X &); };", - cxxMethodDecl(isCopyAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(const X &); };", - cxxMethodDecl(isCopyAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", - cxxMethodDecl(isCopyAssignmentOperator()))); + auto CopyAssignment = + cxxMethodDecl(isCopyAssignmentOperator(), unless(isImplicit())); + EXPECT_TRUE(matches("class X { X &operator=(X); };", CopyAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(X &); };", CopyAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(const X &); };", CopyAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", // + CopyAssignment)); EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };", - cxxMethodDecl(isCopyAssignmentOperator()))); - EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", - cxxMethodDecl(isCopyAssignmentOperator()))); + CopyAssignment)); + EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", CopyAssignment)); } TEST(Matcher, MatchesMoveAssignmentOperator) { - EXPECT_TRUE(notMatches("class X { X &operator=(X); };", - cxxMethodDecl(isMoveAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(X &&); };", - cxxMethodDecl(isMoveAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", - cxxMethodDecl(isMoveAssignmentOperator()))); - EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", - cxxMethodDecl(isMoveAssignmentOperator()))); + auto MoveAssignment = + cxxMethodDecl(isMoveAssignmentOperator(), unless(isImplicit())); + EXPECT_TRUE(notMatches("class X { X &operator=(X); };", MoveAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(X &&); };", MoveAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", // + MoveAssignment)); + EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", // + MoveAssignment)); EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };", - cxxMethodDecl(isMoveAssignmentOperator()))); - EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", - cxxMethodDecl(isMoveAssignmentOperator()))); + MoveAssignment)); + EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", MoveAssignment)); } TEST(Matcher, MatchesConstMethod) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits