[clang] 70770a1 - Revert "[Clang] Implement P0848 (Conditionally Trivial Special Member Functions)"

Roy Jacobson via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 24 23:12:09 PDT 2022


Author: Roy Jacobson
Date: 2022-08-25T09:11:06+03:00
New Revision: 70770a16bcfa70b2a4b38d55ab8097f9f92c2326

URL: https://github.com/llvm/llvm-project/commit/70770a16bcfa70b2a4b38d55ab8097f9f92c2326
DIFF: https://github.com/llvm/llvm-project/commit/70770a16bcfa70b2a4b38d55ab8097f9f92c2326.diff

LOG: Revert "[Clang] Implement P0848 (Conditionally Trivial Special Member Functions)"

See bug report here: https://github.com/llvm/llvm-project/issues/57351
This reverts commit 7171615099142ed49042c0f27af437b05150dd9b.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/DeclCXX.cpp
    clang/lib/Frontend/InitPreprocessor.cpp
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/www/cxx_status.html

Removed: 
    clang/test/AST/conditionally-trivial-smfs.cpp
    clang/test/SemaCXX/constrained-special-member-functions.cpp


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6109f4e8ac6bc..46339ff9ce8d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -167,10 +167,6 @@ C++20 Feature Support
   (C++14 [dcl.constexpr]p6 (CWG DR647/CWG DR1358))
 - Correctly defer dependent immediate function invocations until template instantiation.
   This fixes `GH55601 <https://github.com/llvm/llvm-project/issues/55601>`_.
-- Implemented "Conditionally Trivial Special Member Functions" (`P0848 <https://wg21.link/p0848r3>`_).
-  Note: The handling of deleted functions is not yet compliant, as Clang
-  does not implement `DR1496 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496>`_
-  and `DR1734 <https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1734>`_.
 
 
 

diff  --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 4e259df1b95e1..38c46b112b803 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -894,11 +894,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
         // This is an extension in C++03.
         data().PlainOldData = false;
       }
-      // When instantiating a class, we delay updating the destructor and
-      // triviality properties of the class until selecting a destructor and
-      // computing the eligibility of its special member functions. This is
-      // because there might be function constraints that we need to evaluate
-      // and compare later in the instantiation.
+      // We delay updating destructor relevant properties until
+      // addedSelectedDestructor.
+      // FIXME: Defer this for the other special member functions as well.
       if (!Method->isIneligibleOrNotSelected()) {
         addedEligibleSpecialMemberFunction(Method, SMKind);
       }
@@ -1439,12 +1437,10 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
 
   // Update which trivial / non-trivial special members we have.
   // addedMember will have skipped this step for this member.
-  if (!D->isIneligibleOrNotSelected()) {
-    if (D->isTrivial())
-      data().HasTrivialSpecialMembers |= SMKind;
-    else
-      data().DeclaredNonTrivialSpecialMembers |= SMKind;
-  }
+  if (D->isTrivial())
+    data().HasTrivialSpecialMembers |= SMKind;
+  else
+    data().DeclaredNonTrivialSpecialMembers |= SMKind;
 }
 
 void CXXRecordDecl::setCaptures(ASTContext &Context,

diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index eff811e113e5e..20bfbf144a30a 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -674,9 +674,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
   // C++20 features.
   if (LangOpts.CPlusPlus20) {
     //Builder.defineMacro("__cpp_aggregate_paren_init", "201902L");
-    // P0848 is implemented, but we're still waiting for other concepts
-    // issues to be addressed before bumping __cpp_concepts up to 202002L.
-    // Refer to the discussion of this at https://reviews.llvm.org/D128619.
     Builder.defineMacro("__cpp_concepts", "201907L");
     Builder.defineMacro("__cpp_conditional_explicit", "201806L");
     //Builder.defineMacro("__cpp_consteval", "201811L");

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ef59ecebb70ac..88939597c454b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -17968,6 +17968,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
   AllIvarDecls.push_back(Ivar);
 }
 
+namespace {
 /// [class.dtor]p4:
 ///   At the end of the definition of a class, overload resolution is
 ///   performed among the prospective destructors declared in that class with
@@ -17976,7 +17977,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
 ///
 /// We do the overload resolution here, then mark the selected constructor in the AST.
 /// Later CXXRecordDecl::getDestructor() will return the selected constructor.
-static void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
+void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
   if (!Record->hasUserDeclaredDestructor()) {
     return;
   }
@@ -18034,130 +18035,7 @@ static void ComputeSelectedDestructor(Sema &S, CXXRecordDecl *Record) {
     Record->addedSelectedDestructor(dyn_cast<CXXDestructorDecl>(OCS.begin()->Function));
   }
 }
-
-/// [class.mem.special]p5
-/// Two special member functions are of the same kind if:
-/// - they are both default constructors,
-/// - they are both copy or move constructors with the same first parameter
-///   type, or
-/// - they are both copy or move assignment operators with the same first
-///   parameter type and the same cv-qualifiers and ref-qualifier, if any.
-static bool AreSpecialMemberFunctionsSameKind(ASTContext &Context,
-                                              CXXMethodDecl *M1,
-                                              CXXMethodDecl *M2,
-                                              Sema::CXXSpecialMember CSM) {
-  if (CSM == Sema::CXXDefaultConstructor)
-    return true;
-  if (!Context.hasSameType(M1->getParamDecl(0)->getType(),
-                           M2->getParamDecl(0)->getType()))
-    return false;
-  if (!Context.hasSameType(M1->getThisType(), M2->getThisType()))
-    return false;
-
-  return true;
-}
-
-/// [class.mem.special]p6:
-/// An eligible special member function is a special member function for which:
-/// - the function is not deleted,
-/// - the associated constraints, if any, are satisfied, and
-/// - no special member function of the same kind whose associated constraints
-///   [CWG2595], if any, are satisfied is more constrained.
-static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
-                               ArrayRef<CXXMethodDecl *> Methods,
-                               Sema::CXXSpecialMember CSM) {
-  SmallVector<bool, 4> SatisfactionStatus;
-
-  for (CXXMethodDecl *Method : Methods) {
-    const Expr *Constraints = Method->getTrailingRequiresClause();
-    if (!Constraints)
-      SatisfactionStatus.push_back(true);
-    else {
-      ConstraintSatisfaction Satisfaction;
-      if (S.CheckFunctionConstraints(Method, Satisfaction))
-        SatisfactionStatus.push_back(false);
-      else
-        SatisfactionStatus.push_back(Satisfaction.IsSatisfied);
-    }
-  }
-
-  for (size_t i = 0; i < Methods.size(); i++) {
-    if (!SatisfactionStatus[i])
-      continue;
-    CXXMethodDecl *Method = Methods[i];
-    const Expr *Constraints = Method->getTrailingRequiresClause();
-    bool AnotherMethodIsMoreConstrained = false;
-    for (size_t j = 0; j < Methods.size(); j++) {
-      if (i == j || !SatisfactionStatus[j])
-        continue;
-      CXXMethodDecl *OtherMethod = Methods[j];
-      if (!AreSpecialMemberFunctionsSameKind(S.Context, Method, OtherMethod,
-                                             CSM))
-        continue;
-
-      const Expr *OtherConstraints = OtherMethod->getTrailingRequiresClause();
-      if (!OtherConstraints)
-        continue;
-      if (!Constraints) {
-        AnotherMethodIsMoreConstrained = true;
-        break;
-      }
-      if (S.IsAtLeastAsConstrained(OtherMethod, {OtherConstraints}, Method,
-                                   {Constraints},
-                                   AnotherMethodIsMoreConstrained)) {
-        // There was an error with the constraints comparison. Exit the loop
-        // and don't consider this function eligible.
-        AnotherMethodIsMoreConstrained = true;
-      }
-      if (AnotherMethodIsMoreConstrained)
-        break;
-    }
-    // FIXME: Do not consider deleted methods as eligible after implementing
-    // DR1734 and DR1496.
-    if (!AnotherMethodIsMoreConstrained) {
-      Method->setIneligibleOrNotSelected(false);
-      Record->addedEligibleSpecialMemberFunction(Method, 1 << CSM);
-    }
-  }
-}
-
-static void ComputeSpecialMemberFunctionsEligiblity(Sema &S,
-                                                    CXXRecordDecl *Record) {
-  SmallVector<CXXMethodDecl *, 4> DefaultConstructors;
-  SmallVector<CXXMethodDecl *, 4> CopyConstructors;
-  SmallVector<CXXMethodDecl *, 4> MoveConstructors;
-  SmallVector<CXXMethodDecl *, 4> CopyAssignmentOperators;
-  SmallVector<CXXMethodDecl *, 4> MoveAssignmentOperators;
-
-  for (auto *Decl : Record->decls()) {
-    auto *MD = dyn_cast<CXXMethodDecl>(Decl);
-    if (!MD)
-      continue;
-    if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
-      if (CD->isInvalidDecl())
-        continue;
-      if (CD->isDefaultConstructor())
-        DefaultConstructors.push_back(MD);
-      else if (CD->isCopyConstructor())
-        CopyConstructors.push_back(MD);
-      else if (CD->isMoveConstructor())
-        MoveConstructors.push_back(MD);
-    } else if (MD->isCopyAssignmentOperator()) {
-      CopyAssignmentOperators.push_back(MD);
-    } else if (MD->isMoveAssignmentOperator()) {
-      MoveAssignmentOperators.push_back(MD);
-    }
-  }
-
-  SetEligibleMethods(S, Record, DefaultConstructors,
-                     Sema::CXXDefaultConstructor);
-  SetEligibleMethods(S, Record, CopyConstructors, Sema::CXXCopyConstructor);
-  SetEligibleMethods(S, Record, MoveConstructors, Sema::CXXMoveConstructor);
-  SetEligibleMethods(S, Record, CopyAssignmentOperators,
-                     Sema::CXXCopyAssignment);
-  SetEligibleMethods(S, Record, MoveAssignmentOperators,
-                     Sema::CXXMoveAssignment);
-}
+} // namespace
 
 void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
                        ArrayRef<Decl *> Fields, SourceLocation LBrac,
@@ -18185,6 +18063,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
   RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
   CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(EnclosingDecl);
 
+  if (CXXRecord && !CXXRecord->isDependentType())
+    ComputeSelectedDestructor(*this, CXXRecord);
+
   // Start counting up the number of named members; make sure to include
   // members of anonymous structs and unions in the total.
   unsigned NumNamedMembers = 0;
@@ -18470,8 +18351,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
             Completed = true;
           }
         }
-        ComputeSelectedDestructor(*this, CXXRecord);
-        ComputeSpecialMemberFunctionsEligiblity(*this, CXXRecord);
       }
     }
 

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 198de680ae3d4..9ab009488c955 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6618,7 +6618,7 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
     bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;
     bool DtorIsTrivialForCall = false;
 
-    // If a class has at least one eligible, trivial copy constructor, it
+    // If a class has at least one non-deleted, trivial copy constructor, it
     // is passed according to the C ABI. Otherwise, it is passed indirectly.
     //
     // Note: This permits classes with non-trivial copy or move ctors to be
@@ -6633,8 +6633,7 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
       }
     } else {
       for (const CXXConstructorDecl *CD : D->ctors()) {
-        if (CD->isCopyConstructor() && !CD->isDeleted() &&
-            !CD->isIneligibleOrNotSelected()) {
+        if (CD->isCopyConstructor() && !CD->isDeleted()) {
           if (CD->isTrivial())
             CopyCtorIsTrivial = true;
           if (CD->isTrivialForCall())

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 24ea3254cb272..cce054d11dc8b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2481,9 +2481,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
         Constructor->getConstexprKind(), InheritedConstructor(),
         TrailingRequiresClause);
     Method->setRangeEnd(Constructor->getEndLoc());
-    if (Constructor->isDefaultConstructor() ||
-        Constructor->isCopyOrMoveConstructor())
-      Method->setIneligibleOrNotSelected(true);
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
     Method = CXXDestructorDecl::Create(
         SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
@@ -2506,8 +2503,6 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
         SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC,
         D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(),
         D->getEndLoc(), TrailingRequiresClause);
-    if (D->isMoveAssignmentOperator() || D->isCopyAssignmentOperator())
-      Method->setIneligibleOrNotSelected(true);
   }
 
   if (D->isInlined())

diff  --git a/clang/test/AST/conditionally-trivial-smfs.cpp b/clang/test/AST/conditionally-trivial-smfs.cpp
deleted file mode 100644
index 34db1cd8d3611..0000000000000
--- a/clang/test/AST/conditionally-trivial-smfs.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-linux -ast-dump=json %s | FileCheck %s --check-prefixes=CHECK,LIN
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-win32 -ast-dump=json %s | FileCheck %s
-
-// This test validates that we compute correct AST properties of classes with
-// conditionally trivial special member functions.
-
-template <int N>
-struct DefaultConstructorCheck {
-  DefaultConstructorCheck() requires(N == 1) = default;
-  DefaultConstructorCheck() requires(N == 2) = delete;
-  DefaultConstructorCheck() requires(N == 3);
-  DefaultConstructorCheck();
-};
-
-
-template struct DefaultConstructorCheck<1>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "defaultCtor": {
-// CHECK-NEXT:            "defaultedIsConstexpr": true,
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "isConstexpr": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userProvided": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTrivial": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-
-template struct DefaultConstructorCheck<2>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "defaultCtor": {
-// CHECK-NEXT:            "defaultedIsConstexpr": true,
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "isConstexpr": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userProvided": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTrivial": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-
-
-template struct DefaultConstructorCheck<3>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "defaultCtor": {
-// CHECK-NEXT:            "defaultedIsConstexpr": true,
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "isConstexpr": true,
-// CHECK-NEXT:            "nonTrivial": true,
-// CHECK-NEXT:            "userProvided": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-
-template <int N>
-struct CopyConstructorCheck {
-  CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 1) = default;
-  CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 2) = delete;
-  CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 3);
-  CopyConstructorCheck(const CopyConstructorCheck&);
-};
-
-
-template struct CopyConstructorCheck<1>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "copyCtor": {
-// CHECK-NEXT:            "hasConstParam": true,
-// CHECK-NEXT:            "implicitHasConstParam": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {},
-
-template struct CopyConstructorCheck<2>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "copyCtor": {
-// CHECK-NEXT:            "hasConstParam": true,
-// CHECK-NEXT:            "implicitHasConstParam": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {},
-
-template struct CopyConstructorCheck<3>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "copyCtor": {
-// CHECK-NEXT:            "hasConstParam": true,
-// CHECK-NEXT:            "implicitHasConstParam": true,
-// CHECK-NEXT:            "nonTrivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "moveAssign": {},
-
-template <int N>
-struct MoveConstructorCheck {
-  MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 1) = default;
-  MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 2) = delete;
-  MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 3);
-  MoveConstructorCheck(MoveConstructorCheck&&);
-};
-
-
-template struct MoveConstructorCheck<1>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// LIN-NEXT:            "canPassInRegisters": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {},
-// CHECK-NEXT:          "moveCtor": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          }
-
-template struct MoveConstructorCheck<2>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {},
-// CHECK-NEXT:          "moveCtor": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          }
-
-template struct MoveConstructorCheck<3>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasUserDeclaredConstructor": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "moveAssign": {},
-// CHECK-NEXT:          "moveCtor": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "nonTrivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          }
-
-template <int N>
-struct CopyAssignmentCheck {
-  CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 1) = default;
-  CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 2) = delete;
-  CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 3);
-  CopyAssignmentCheck& operator=(const CopyAssignmentCheck&);
-};
-
-
-template struct CopyAssignmentCheck<1>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT           "copyAssign": {
-// CHECK-NEXT             "hasConstParam": true,
-// CHECK-NEXT             "implicitHasConstParam": true,
-// CHECK-NEXT             "trivial": true,
-// CHECK-NEXT             "userDeclared": true
-// CHECK-NEXT           },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT           "isAggregate": true,
-// CHECK-NEXT           "isEmpty": true,
-// CHECK-NEXT           "isLiteral": true,
-// CHECK-NEXT           "isStandardLayout": true,
-// CHECK-NEXT           "isTrivial": true,
-// CHECK-NEXT           "isTriviallyCopyable": true,
-// CHECK-NEXT           "moveAssign": {},
-
-template struct CopyAssignmentCheck<2>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT           "copyAssign": {
-// CHECK-NEXT             "hasConstParam": true,
-// CHECK-NEXT             "implicitHasConstParam": true,
-// CHECK-NEXT             "trivial": true,
-// CHECK-NEXT             "userDeclared": true
-// CHECK-NEXT           },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT           "isAggregate": true,
-// CHECK-NEXT           "isEmpty": true,
-// CHECK-NEXT           "isLiteral": true,
-// CHECK-NEXT           "isStandardLayout": true,
-// CHECK-NEXT           "isTrivial": true,
-// CHECK-NEXT           "isTriviallyCopyable": true,
-// CHECK-NEXT           "moveAssign": {},
-
-template struct CopyAssignmentCheck<3>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "canPassInRegisters": true,
-// CHECK-NEXT           "copyAssign": {
-// CHECK-NEXT             "hasConstParam": true,
-// CHECK-NEXT             "implicitHasConstParam": true,
-// CHECK-NEXT             "trivial": true,
-// CHECK-NEXT             "userDeclared": true
-// CHECK-NEXT           },
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT           "isAggregate": true,
-// CHECK-NEXT           "isEmpty": true,
-// CHECK-NEXT           "isLiteral": true,
-// CHECK-NEXT           "isStandardLayout": true,
-// CHECK-NEXT           "moveAssign": {},
-
-template <int N>
-struct MoveAssignmentCheck {
-  MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 1) = default;
-  MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 2) = delete;
-  MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 3);
-  MoveAssignmentCheck& operator=(MoveAssignmentCheck&&);
-};
-
-
-template struct MoveAssignmentCheck<1>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "isAggregate": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTrivial": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },
-
-template struct MoveAssignmentCheck<2>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "isAggregate": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "isTrivial": true,
-// CHECK-NEXT:          "isTriviallyCopyable": true,
-// CHECK-NEXT:          "moveAssign": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "trivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },
-
-template struct MoveAssignmentCheck<3>;
-// CHECK:             "kind": "ClassTemplateSpecializationDecl",
-// CHECK:             "definitionData": {
-// CHECK-NEXT:          "canConstDefaultInit": true,
-// CHECK-NEXT:          "copyAssign": {
-
-// CHECK:               "hasConstexprNonCopyMoveConstructor": true,
-// CHECK-NEXT:          "isAggregate": true,
-// CHECK-NEXT:          "isEmpty": true,
-// CHECK-NEXT:          "isLiteral": true,
-// CHECK-NEXT:          "isStandardLayout": true,
-// CHECK-NEXT:          "moveAssign": {
-// CHECK-NEXT:            "exists": true,
-// CHECK-NEXT:            "nonTrivial": true,
-// CHECK-NEXT:            "userDeclared": true
-// CHECK-NEXT:          },

diff  --git a/clang/test/SemaCXX/constrained-special-member-functions.cpp b/clang/test/SemaCXX/constrained-special-member-functions.cpp
deleted file mode 100644
index b3eb2c0eaf5f4..0000000000000
--- a/clang/test/SemaCXX/constrained-special-member-functions.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-// RUN: %clang_cc1 -verify -std=c++20 %s
-
-template <int N>
-concept C0 = (N == 0);
-template <int N>
-concept C1 = (N == 1);
-template <int N>
-concept C2 = (N == 2);
-
-// Checks are indexed by:
-// Definition:
-//  1. Explicitly defaulted definition
-//  2. Deleted definition
-//  3. User provided definition
-// We have a less constrained user provided method that should not disable
-// the (copyable) triviality of the type.
-
-// Note that because Clang does not implement DRs 1496 and 1734, we say some
-// classes are trivial when the SMFs are deleted.
-
-template <int N>
-struct DefaultConstructorChecker {
-    DefaultConstructorChecker() requires C0<N> = default;
-    DefaultConstructorChecker() requires C1<N> = delete;
-    DefaultConstructorChecker() requires C2<N>;
-    DefaultConstructorChecker();
-};
-static_assert(__is_trivially_copyable(DefaultConstructorChecker<0>));
-static_assert(__is_trivially_copyable(DefaultConstructorChecker<1>));
-static_assert(__is_trivially_copyable(DefaultConstructorChecker<2>));
-static_assert(__is_trivially_copyable(DefaultConstructorChecker<3>));
-static_assert(__is_trivial(DefaultConstructorChecker<0>));
-// FIXME: DR1496
-static_assert(__is_trivial(DefaultConstructorChecker<1>));
-static_assert(!__is_trivial(DefaultConstructorChecker<2>));
-static_assert(!__is_trivial(DefaultConstructorChecker<3>));
-
-template <int N>
-struct CopyConstructorChecker {
-    CopyConstructorChecker(const CopyConstructorChecker&) requires C0<N> = default;
-    CopyConstructorChecker(const CopyConstructorChecker&) requires C1<N> = delete;
-    CopyConstructorChecker(const CopyConstructorChecker&) requires C2<N>;
-    CopyConstructorChecker(const CopyConstructorChecker&);
-};
-
-static_assert(__is_trivially_copyable(CopyConstructorChecker<0>));
-// FIXME: DR1734
-static_assert(__is_trivially_copyable(CopyConstructorChecker<1>));
-static_assert(!__is_trivially_copyable(CopyConstructorChecker<2>));
-static_assert(!__is_trivially_copyable(CopyConstructorChecker<3>));
-static_assert(!__is_trivial(CopyConstructorChecker<0>));
-static_assert(!__is_trivial(CopyConstructorChecker<1>));
-static_assert(!__is_trivial(CopyConstructorChecker<2>));
-static_assert(!__is_trivial(CopyConstructorChecker<3>));
-
-template <int N>
-struct MoveConstructorChecker {
-    MoveConstructorChecker(MoveConstructorChecker&&) requires C0<N> = default;
-    MoveConstructorChecker(MoveConstructorChecker&&) requires C1<N> = delete;
-    MoveConstructorChecker(MoveConstructorChecker&&) requires C2<N>;
-    MoveConstructorChecker(MoveConstructorChecker&&);
-};
-
-static_assert(__is_trivially_copyable(MoveConstructorChecker<0>));
-// FIXME: DR1734
-static_assert(__is_trivially_copyable(MoveConstructorChecker<1>));
-static_assert(!__is_trivially_copyable(MoveConstructorChecker<2>));
-static_assert(!__is_trivially_copyable(MoveConstructorChecker<3>));
-static_assert(!__is_trivial(MoveConstructorChecker<0>));
-static_assert(!__is_trivial(MoveConstructorChecker<1>));
-static_assert(!__is_trivial(MoveConstructorChecker<2>));
-static_assert(!__is_trivial(MoveConstructorChecker<3>));
-
-template <int N>
-struct MoveAssignmentChecker {
-    MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C0<N> = default;
-    MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C1<N> = delete;
-    MoveAssignmentChecker& operator=(MoveAssignmentChecker&&) requires C2<N>;
-    MoveAssignmentChecker& operator=(MoveAssignmentChecker&&);
-};
-
-static_assert(__is_trivially_copyable(MoveAssignmentChecker<0>));
-// FIXME: DR1734.
-static_assert(__is_trivially_copyable(MoveAssignmentChecker<1>));
-static_assert(!__is_trivially_copyable(MoveAssignmentChecker<2>));
-static_assert(!__is_trivially_copyable(MoveAssignmentChecker<3>));
-static_assert(__is_trivial(MoveAssignmentChecker<0>));
-// FIXME: DR1734.
-static_assert(__is_trivial(MoveAssignmentChecker<1>));
-static_assert(!__is_trivial(MoveAssignmentChecker<2>));
-static_assert(!__is_trivial(MoveAssignmentChecker<3>));
-
-template <int N>
-struct CopyAssignmentChecker {
-    CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C0<N> = default;
-    CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C1<N> = delete;
-    CopyAssignmentChecker& operator=(const CopyAssignmentChecker&) requires C2<N>;
-    CopyAssignmentChecker& operator=(const CopyAssignmentChecker&);
-};
-
-static_assert(__is_trivially_copyable(CopyAssignmentChecker<0>));
-// FIXME: DR1734.
-static_assert(__is_trivially_copyable(CopyAssignmentChecker<1>));
-static_assert(!__is_trivially_copyable(CopyAssignmentChecker<2>));
-static_assert(!__is_trivially_copyable(CopyAssignmentChecker<3>));
-static_assert(__is_trivial(CopyAssignmentChecker<0>));
-// FIXME: DR1734.
-static_assert(__is_trivial(CopyAssignmentChecker<1>));
-static_assert(!__is_trivial(CopyAssignmentChecker<2>));
-static_assert(!__is_trivial(CopyAssignmentChecker<3>));
-
-
-template <int N>
-struct KindComparisonChecker1 {
-    KindComparisonChecker1& operator=(const KindComparisonChecker1&) requires C0<N> = default;
-    KindComparisonChecker1& operator=(KindComparisonChecker1&);
-};
-
-template <int N>
-struct KindComparisonChecker2 {
-    KindComparisonChecker2& operator=(const KindComparisonChecker2&) requires C0<N> = default;
-    const KindComparisonChecker2& operator=(KindComparisonChecker2&) const;
-};
-
-template <int N>
-struct KindComparisonChecker3 {
-    using Alias = KindComparisonChecker3;
-    Alias& operator=(const Alias&) requires C0<N> = default;
-    KindComparisonChecker3& operator=(const KindComparisonChecker3&);
-};
-
-static_assert(!__is_trivial(KindComparisonChecker1<0>));
-static_assert(!__is_trivially_copyable(KindComparisonChecker1<0>));
-
-static_assert(!__is_trivial(KindComparisonChecker2<0>));
-static_assert(!__is_trivially_copyable(KindComparisonChecker2<0>));
-
-static_assert(__is_trivial(KindComparisonChecker3<0>));
-static_assert(__is_trivially_copyable(KindComparisonChecker3<0>));
-
-template <class T>
-concept HasA = requires(T t) {
-    { t.a() };
-};
-
-template <class T>
-concept HasAB = HasA<T> && requires(T t) {
-    { t.b() };
-};
-
-template <class T>
-concept HasAC = HasA<T> && requires(T t) {
-    { t.c() };
-};
-
-template <class T>
-concept HasABC = HasAB<T> && HasAC<T> && requires(T t) {
-    { t.c() };
-};
-
-template <class T>
-struct ComplexConstraints {
-    ComplexConstraints() requires HasABC<T> = default;
-    ComplexConstraints() requires HasAB<T>;
-    ComplexConstraints() requires HasAC<T>;
-    ComplexConstraints() requires HasA<T> = delete;
-    ComplexConstraints();
-};
-
-struct A {
-    void a();
-};
-
-struct AB {
-    void a();
-    void b();
-};
-
-struct ABC {
-    void a();
-    void b();
-    void c();
-};
-
-struct AC {
-    void a();
-    void c();
-};
-
-static_assert(__is_trivial(ComplexConstraints<ABC>), "");
-static_assert(!__is_trivial(ComplexConstraints<AB>), "");
-static_assert(!__is_trivial(ComplexConstraints<AC>), "");
-static_assert(__is_trivial(ComplexConstraints<A>), "");
-static_assert(!__is_trivial(ComplexConstraints<int>), "");
-
-
-// This is evaluated at the completion of CRTPBase, while `T` is not yet completed.
-// This is probably correct behavior.
-// FIXME: We should not throw an error, instead SFINAE should make the constraint
-// silently unsatisfied. See [temp.constr.constr]p5
-template <class T>
-struct CRTPBase {
-  CRTPBase() requires (sizeof(T) > 0); // expected-error {{to an incomplete type}}
-  CRTPBase() = default;
-};
-
-struct Child : CRTPBase<Child> { int x; };
-// expected-note at -1 {{definition of 'Child' is not complete until}}
-// expected-note at -2 {{in instantiation of template class 'CRTPBase<Child>' requested here}}
-static Child c;
-
-
-namespace GH57046 {
-template<unsigned N>
-struct Foo {
-  Foo() requires (N==1) {} // expected-note {{declared here}}
-  Foo() requires (N==2) = default;
-};
-
-template <unsigned N, unsigned M>
-struct S {
-  Foo<M> data;
-  S() requires (N==1) {}
-  consteval S() requires (N==2) = default; // expected-note {{non-constexpr constructor 'Foo' cannot be used in a constant expression}}
-};
-
-void func() {
-  S<2, 1> s1; // expected-error {{is not a constant expression}} expected-note {{in call to 'S()'}}
-  S<2, 2> s2;
-}
-}

diff  --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 5876e39a0b536..5aae4ba822826 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -927,16 +927,8 @@ <h2 id="cxx20">C++20 implementation status</h2>
       </tr>
       <tr> <!-- from Cologne -->
         <td><a href="https://wg21.link/p0848r3">P0848R3</a></td>
-        <td rowspan="1" class="unreleased" align="center">
-          <details>
-            <summary>Clang 16 (Partial)</summary>
-            Because of other concepts implementation deficits, the __cpp_concepts macro is not yet set to 202002L.
-            Also, the related defect reports <a href="https://wg21.link/cwg1496">DR1496</a> and
-            <a href="https://wg21.link/cwg1734">DR1734</a> are not yet implemented. Accordingly, deleted
-            special member functions are treated as eligible even though they shouldn't be.
-          </details>
-        </td>
-        </tr>
+        <td rowspan="1" class="none" align="center">No</td>
+      </tr>
       <tr>
         <td><a href="https://wg21.link/p1616r1">P1616R1</a></td>
         <td rowspan="2" class="full" align="center">Clang 10</td>


        


More information about the cfe-commits mailing list