https://github.com/pcc created https://github.com/llvm/llvm-project/pull/94831
C++17 added the following requirement for a class to be trivially copyable: "that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator". However, this was not implemented. Fix it. >From f725de0cd89b0dd90ce5209cb6b3d9632a52f3c9 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne <p...@google.com> Date: Fri, 7 Jun 2024 20:14:15 -0700 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 --- .../clang/AST/CXXRecordDeclDefinitionBits.def | 3 +++ clang/lib/AST/DeclCXX.cpp | 25 ++++++++++++++++--- clang/test/SemaCXX/type-traits.cpp | 8 ++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index cdf0804680ad0..55cd45348d29d 100644 --- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -249,4 +249,7 @@ FIELD(HasDeclaredCopyAssignmentWithConstParam, 1, MERGE_OR) /// base classes or fields have a no-return destructor FIELD(IsAnyDestructorNoReturn, 1, NO_MERGE) +/// The special members of this class which were deleted. +FIELD(HasDeletedSpecialMembers, 6, MERGE_OR) + #undef FIELD diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 7f2c786547b9b..a3de4d3654006 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -109,9 +109,9 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), - IsAnyDestructorNoReturn(false), IsLambda(false), - IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false), - HasODRHash(false), Definition(D) {} + IsAnyDestructorNoReturn(false), HasDeletedSpecialMembers(0), + IsLambda(false), IsParsingBaseSpecifiers(false), + ComputedVisibleConversions(false), HasODRHash(false), Definition(D) {} CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { return Bases.get(Definition->getASTContext().getExternalSource()); @@ -586,6 +586,14 @@ bool CXXRecordDecl::isTriviallyCopyable() const { if (hasNonTrivialMoveAssignment()) return false; // -- has a trivial destructor. if (!hasTrivialDestructor()) return false; + // C++17 [class]p6: that has at least one non-deleted copy constructor, move + // constructor, copy assignment operator, or move assignment operator, + if (getASTContext().getLangOpts().CPlusPlus17 && + (data().HasDeletedSpecialMembers & + (SMF_CopyAssignment | SMF_CopyConstructor | SMF_MoveAssignment | + SMF_MoveConstructor)) == (SMF_CopyAssignment | SMF_CopyConstructor | + SMF_MoveAssignment | SMF_MoveConstructor)) + return false; return true; } @@ -1446,7 +1454,10 @@ void CXXRecordDecl::addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD, // out whether it's trivial yet (not until we get to the end of the // class). We'll handle this method in // finishedDefaultedOrDeletedMember. - } else if (MD->isTrivial()) { + return; + } + + if (MD->isTrivial()) { data().HasTrivialSpecialMembers |= SMKind; data().HasTrivialSpecialMembersForCall |= SMKind; } else if (MD->isTrivialForCall()) { @@ -1462,6 +1473,10 @@ void CXXRecordDecl::addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD, if (!MD->isUserProvided()) data().DeclaredNonTrivialSpecialMembersForCall |= SMKind; } + + if (MD->isDeleted()) { + data().HasDeletedSpecialMembers |= SMKind; + } } void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { @@ -1499,6 +1514,8 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { data().HasTrivialSpecialMembers |= SMKind; else data().DeclaredNonTrivialSpecialMembers |= SMKind; + if (D->isDeleted()) + data().HasDeletedSpecialMembers |= SMKind; } } diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index d40605f56f1ed..27b0d204d5690 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -1377,7 +1377,11 @@ void is_trivial2() static_assert(__is_trivial(UnionAr)); static_assert(__is_trivial(TrivialStruct)); static_assert(__is_trivial(AllDefaulted)); +#if __cplusplus >= 201703L + static_assert(!__is_trivial(AllDeleted)); +#else static_assert(__is_trivial(AllDeleted)); +#endif static_assert(!__is_trivial(void)); static_assert(!__is_trivial(NonTrivialStruct)); @@ -1419,7 +1423,11 @@ void is_trivially_copyable2() static_assert(__is_trivially_copyable(TrivialStruct)); static_assert(__is_trivially_copyable(NonTrivialStruct)); static_assert(__is_trivially_copyable(AllDefaulted)); +#if __cplusplus >= 201703L + static_assert(!__is_trivially_copyable(AllDeleted)); +#else static_assert(__is_trivially_copyable(AllDeleted)); +#endif static_assert(!__is_trivially_copyable(void)); static_assert(!__is_trivially_copyable(SuperNonTrivialStruct)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits