Skip to content

Commit 70770a1

Browse files
committed
Revert "[Clang] Implement P0848 (Conditionally Trivial Special Member Functions)"
See bug report here: llvm#57351 This reverts commit 7171615.
1 parent 3922ec4 commit 70770a1

File tree

9 files changed

+17
-737
lines changed

9 files changed

+17
-737
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,6 @@ C++20 Feature Support
167167
(C++14 [dcl.constexpr]p6 (CWG DR647/CWG DR1358))
168168
- Correctly defer dependent immediate function invocations until template instantiation.
169169
This fixes `GH55601 <https://github.com/llvm/llvm-project/issues/55601>`_.
170-
- Implemented "Conditionally Trivial Special Member Functions" (`P0848 <https://wg21.link/p0848r3>`_).
171-
Note: The handling of deleted functions is not yet compliant, as Clang
172-
does not implement `DR1496 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496>`_
173-
and `DR1734 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1734>`_.
174170

175171

176172

clang/lib/AST/DeclCXX.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -894,11 +894,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
894894
// This is an extension in C++03.
895895
data().PlainOldData = false;
896896
}
897-
// When instantiating a class, we delay updating the destructor and
898-
// triviality properties of the class until selecting a destructor and
899-
// computing the eligibility of its special member functions. This is
900-
// because there might be function constraints that we need to evaluate
901-
// and compare later in the instantiation.
897+
// We delay updating destructor relevant properties until
898+
// addedSelectedDestructor.
899+
// FIXME: Defer this for the other special member functions as well.
902900
if (!Method->isIneligibleOrNotSelected()) {
903901
addedEligibleSpecialMemberFunction(Method, SMKind);
904902
}
@@ -1439,12 +1437,10 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
14391437

14401438
// Update which trivial / non-trivial special members we have.
14411439
// addedMember will have skipped this step for this member.
1442-
if (!D->isIneligibleOrNotSelected()) {
1443-
if (D->isTrivial())
1444-
data().HasTrivialSpecialMembers |= SMKind;
1445-
else
1446-
data().DeclaredNonTrivialSpecialMembers |= SMKind;
1447-
}
1440+
if (D->isTrivial())
1441+
data().HasTrivialSpecialMembers |= SMKind;
1442+
else
1443+
data().DeclaredNonTrivialSpecialMembers |= SMKind;
14481444
}
14491445

14501446
void CXXRecordDecl::setCaptures(ASTContext &Context,

clang/lib/Frontend/InitPreprocessor.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -674,9 +674,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
674674
// C++20 features.
675675
if (LangOpts.CPlusPlus20) {
676676
//Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");
677-
// P0848 is implemented, but we're still waiting for other concepts
678-
// issues to be addressed before bumping __cpp_concepts up to 202002L.
679-
// Refer to the discussion of this at https://reviews.llvm.org/D128619.
680677
Builder.defineMacro("__cpp_concepts", "201907L");
681678
Builder.defineMacro("__cpp_conditional_explicit", "201806L");
682679
//Builder.defineMacro("__cpp_consteval", "201811L");

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -17968,6 +17968,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
1796817968
AllIvarDecls.push_back(Ivar);
1796917969
}
1797017970

17971+
namespace {
1797117972
/// [class.dtor]p4:
1797217973
/// At the end of the definition of a class, overload resolution is
1797317974
/// performed among the prospective destructors declared in that class with
@@ -17976,7 +17977,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
1797617977
///
1797717978
/// We do the overload resolution here, then mark the selected constructor in the AST.
1797817979
/// Later CXXRecordDecl::getDestructor() will return the selected constructor.
17979-
static void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
17980+
void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
1798017981
if (!Record->hasUserDeclaredDestructor()) {
1798117982
return;
1798217983
}
@@ -18034,130 +18035,7 @@ static void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
1803418035
Record->addedSelectedDestructor(dyn_cast<CXXDestructorDecl>(OCS.begin()->Function));
1803518036
}
1803618037
}
18037-
18038-
/// [class.mem.special]p5
18039-
/// Two special member functions are of the same kind if:
18040-
/// - they are both default constructors,
18041-
/// - they are both copy or move constructors with the same first parameter
18042-
/// type, or
18043-
/// - they are both copy or move assignment operators with the same first
18044-
/// parameter type and the same cv-qualifiers and ref-qualifier, if any.
18045-
static bool AreSpecialMemberFunctionsSameKind(ASTContext &Context,
18046-
CXXMethodDecl *M1,
18047-
CXXMethodDecl *M2,
18048-
Sema::CXXSpecialMember CSM) {
18049-
if (CSM == Sema::CXXDefaultConstructor)
18050-
return true;
18051-
if (!Context.hasSameType(M1->getParamDecl(0)->getType(),
18052-
M2->getParamDecl(0)->getType()))
18053-
return false;
18054-
if (!Context.hasSameType(M1->getThisType(), M2->getThisType()))
18055-
return false;
18056-
18057-
return true;
18058-
}
18059-
18060-
/// [class.mem.special]p6:
18061-
/// An eligible special member function is a special member function for which:
18062-
/// - the function is not deleted,
18063-
/// - the associated constraints, if any, are satisfied, and
18064-
/// - no special member function of the same kind whose associated constraints
18065-
/// [CWG2595], if any, are satisfied is more constrained.
18066-
static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
18067-
ArrayRef<CXXMethodDecl *> Methods,
18068-
Sema::CXXSpecialMember CSM) {
18069-
SmallVector<bool, 4> SatisfactionStatus;
18070-
18071-
for (CXXMethodDecl *Method : Methods) {
18072-
const Expr *Constraints = Method->getTrailingRequiresClause();
18073-
if (!Constraints)
18074-
SatisfactionStatus.push_back(true);
18075-
else {
18076-
ConstraintSatisfaction Satisfaction;
18077-
if (S.CheckFunctionConstraints(Method, Satisfaction))
18078-
SatisfactionStatus.push_back(false);
18079-
else
18080-
SatisfactionStatus.push_back(Satisfaction.IsSatisfied);
18081-
}
18082-
}
18083-
18084-
for (size_t i = 0; i < Methods.size(); i++) {
18085-
if (!SatisfactionStatus[i])
18086-
continue;
18087-
CXXMethodDecl *Method = Methods[i];
18088-
const Expr *Constraints = Method->getTrailingRequiresClause();
18089-
bool AnotherMethodIsMoreConstrained = false;
18090-
for (size_t j = 0; j < Methods.size(); j++) {
18091-
if (i == j || !SatisfactionStatus[j])
18092-
continue;
18093-
CXXMethodDecl *OtherMethod = Methods[j];
18094-
if (!AreSpecialMemberFunctionsSameKind(S.Context, Method, OtherMethod,
18095-
CSM))
18096-
continue;
18097-
18098-
const Expr *OtherConstraints = OtherMethod->getTrailingRequiresClause();
18099-
if (!OtherConstraints)
18100-
continue;
18101-
if (!Constraints) {
18102-
AnotherMethodIsMoreConstrained = true;
18103-
break;
18104-
}
18105-
if (S.IsAtLeastAsConstrained(OtherMethod, {OtherConstraints}, Method,
18106-
{Constraints},
18107-
AnotherMethodIsMoreConstrained)) {
18108-
// There was an error with the constraints comparison. Exit the loop
18109-
// and don't consider this function eligible.
18110-
AnotherMethodIsMoreConstrained = true;
18111-
}
18112-
if (AnotherMethodIsMoreConstrained)
18113-
break;
18114-
}
18115-
// FIXME: Do not consider deleted methods as eligible after implementing
18116-
// DR1734 and DR1496.
18117-
if (!AnotherMethodIsMoreConstrained) {
18118-
Method->setIneligibleOrNotSelected(false);
18119-
Record->addedEligibleSpecialMemberFunction(Method, 1 << CSM);
18120-
}
18121-
}
18122-
}
18123-
18124-
static void ComputeSpecialMemberFunctionsEligiblity(Sema &S,
18125-
CXXRecordDecl *Record) {
18126-
SmallVector<CXXMethodDecl *, 4> DefaultConstructors;
18127-
SmallVector<CXXMethodDecl *, 4> CopyConstructors;
18128-
SmallVector<CXXMethodDecl *, 4> MoveConstructors;
18129-
SmallVector<CXXMethodDecl *, 4> CopyAssignmentOperators;
18130-
SmallVector<CXXMethodDecl *, 4> MoveAssignmentOperators;
18131-
18132-
for (auto *Decl : Record->decls()) {
18133-
auto *MD = dyn_cast<CXXMethodDecl>(Decl);
18134-
if (!MD)
18135-
continue;
18136-
if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
18137-
if (CD->isInvalidDecl())
18138-
continue;
18139-
if (CD->isDefaultConstructor())
18140-
DefaultConstructors.push_back(MD);
18141-
else if (CD->isCopyConstructor())
18142-
CopyConstructors.push_back(MD);
18143-
else if (CD->isMoveConstructor())
18144-
MoveConstructors.push_back(MD);
18145-
} else if (MD->isCopyAssignmentOperator()) {
18146-
CopyAssignmentOperators.push_back(MD);
18147-
} else if (MD->isMoveAssignmentOperator()) {
18148-
MoveAssignmentOperators.push_back(MD);
18149-
}
18150-
}
18151-
18152-
SetEligibleMethods(S, Record, DefaultConstructors,
18153-
Sema::CXXDefaultConstructor);
18154-
SetEligibleMethods(S, Record, CopyConstructors, Sema::CXXCopyConstructor);
18155-
SetEligibleMethods(S, Record, MoveConstructors, Sema::CXXMoveConstructor);
18156-
SetEligibleMethods(S, Record, CopyAssignmentOperators,
18157-
Sema::CXXCopyAssignment);
18158-
SetEligibleMethods(S, Record, MoveAssignmentOperators,
18159-
Sema::CXXMoveAssignment);
18160-
}
18038+
} // namespace
1816118039

1816218040
void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1816318041
ArrayRef<Decl *> Fields, SourceLocation LBrac,
@@ -18185,6 +18063,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1818518063
RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
1818618064
CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(EnclosingDecl);
1818718065

18066+
if (CXXRecord && !CXXRecord->isDependentType())
18067+
ComputeSelectedDestructor(*this, CXXRecord);
18068+
1818818069
// Start counting up the number of named members; make sure to include
1818918070
// members of anonymous structs and unions in the total.
1819018071
unsigned NumNamedMembers = 0;
@@ -18470,8 +18351,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
1847018351
Completed = true;
1847118352
}
1847218353
}
18473-
ComputeSelectedDestructor(*this, CXXRecord);
18474-
ComputeSpecialMemberFunctionsEligiblity(*this, CXXRecord);
1847518354
}
1847618355
}
1847718356

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6618,7 +6618,7 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
66186618
bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;
66196619
bool DtorIsTrivialForCall = false;
66206620

6621-
// If a class has at least one eligible, trivial copy constructor, it
6621+
// If a class has at least one non-deleted, trivial copy constructor, it
66226622
// is passed according to the C ABI. Otherwise, it is passed indirectly.
66236623
//
66246624
// Note: This permits classes with non-trivial copy or move ctors to be
@@ -6633,8 +6633,7 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
66336633
}
66346634
} else {
66356635
for (const CXXConstructorDecl *CD : D->ctors()) {
6636-
if (CD->isCopyConstructor() && !CD->isDeleted() &&
6637-
!CD->isIneligibleOrNotSelected()) {
6636+
if (CD->isCopyConstructor() && !CD->isDeleted()) {
66386637
if (CD->isTrivial())
66396638
CopyCtorIsTrivial = true;
66406639
if (CD->isTrivialForCall())

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,9 +2481,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
24812481
Constructor->getConstexprKind(), InheritedConstructor(),
24822482
TrailingRequiresClause);
24832483
Method->setRangeEnd(Constructor->getEndLoc());
2484-
if (Constructor->isDefaultConstructor() ||
2485-
Constructor->isCopyOrMoveConstructor())
2486-
Method->setIneligibleOrNotSelected(true);
24872484
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
24882485
Method = CXXDestructorDecl::Create(
24892486
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
@@ -2506,8 +2503,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
25062503
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC,
25072504
D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(),
25082505
D->getEndLoc(), TrailingRequiresClause);
2509-
if (D->isMoveAssignmentOperator() || D->isCopyAssignmentOperator())
2510-
Method->setIneligibleOrNotSelected(true);
25112506
}
25122507

25132508
if (D->isInlined())

0 commit comments

Comments
 (0)