[clang] 3b9ed6e - Revert "[Clang][Sema] Fix comparison of constraint expressions"

Alexander Shaposhnikov via cfe-commits cfe-commits at lists.llvm.org
Thu May 4 17:03:37 PDT 2023


Author: Alexander Shaposhnikov
Date: 2023-05-05T00:02:26Z
New Revision: 3b9ed6e5323176550925f3b0a2c50ced1b61438d

URL: https://github.com/llvm/llvm-project/commit/3b9ed6e5323176550925f3b0a2c50ced1b61438d
DIFF: https://github.com/llvm/llvm-project/commit/3b9ed6e5323176550925f3b0a2c50ced1b61438d.diff

LOG: Revert "[Clang][Sema] Fix comparison of constraint expressions"

This reverts commit 3a540229341e3c8dc6d8ee61309eafaf943ea254.
A new regression is discovered and needs to be investigated.

Added: 
    

Modified: 
    clang/include/clang/AST/DeclTemplate.h
    clang/include/clang/Sema/Template.h
    clang/lib/Sema/SemaConcept.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp
    clang/lib/Sema/SemaTemplateInstantiate.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaTemplate/concepts-friends.cpp
    clang/test/SemaTemplate/concepts-out-of-line-def.cpp
    clang/test/SemaTemplate/concepts.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 7cd505218f2b9..3677335fa176f 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -2309,15 +2309,9 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
   }
 
-  void setCommonPtr(Common *C) {
-    RedeclarableTemplateDecl::Common = C;
-  }
-
 public:
-
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
-  friend class TemplateDeclInstantiator;
 
   /// Load any lazily-loaded specializations from the external source.
   void LoadLazySpecializations() const;

diff  --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 1de2cc6917b42..48e8b78311e12 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -232,21 +232,9 @@ enum class TemplateSubstitutionKind : char {
     /// Replaces the current 'innermost' level with the provided argument list.
     /// This is useful for type deduction cases where we need to get the entire
     /// list from the AST, but then add the deduced innermost list.
-    void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
-      assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) &&
-             "Replacing in an empty list?");
-
-      if (!TemplateArgumentLists.empty()) {
-        assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ||
-                TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ==
-                    AssociatedDecl) &&
-               "Trying to change incorrect declaration?");
-        TemplateArgumentLists[0].Args = Args;
-      } else {
-        --NumRetainedOuterLevels;
-        TemplateArgumentLists.push_back(
-            {{AssociatedDecl, /*Final=*/false}, Args});
-      }
+    void replaceInnermostTemplateArguments(ArgList Args) {
+      assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?");
+      TemplateArgumentLists[0].Args = Args;
     }
 
     /// Add an outermost level that we are not substituting. We have no

diff  --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 1126c2c517fe4..7aa06b615fec2 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -722,7 +722,7 @@ CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND,
       ND, /*Final=*/false, /*Innermost=*/nullptr, /*RelativeToPrimary=*/true,
       /*Pattern=*/nullptr,
       /*ForConstraintInstantiation=*/true, SkipForSpecialization);
-  return MLTAL.getNumLevels();
+  return MLTAL.getNumSubstitutedLevels();
 }
 
 namespace {
@@ -753,44 +753,27 @@ namespace {
   };
 } // namespace
 
-static const Expr *SubstituteConstraintExpression(Sema &S, const NamedDecl *ND,
-                                                  const Expr *ConstrExpr) {
-  MultiLevelTemplateArgumentList MLTAL = S.getTemplateInstantiationArgs(
-      ND, /*Final=*/false, /*Innermost=*/nullptr,
-      /*RelativeToPrimary=*/true,
-      /*Pattern=*/nullptr, /*ForConstraintInstantiation=*/true,
-      /*SkipForSpecialization*/ false);
-  if (MLTAL.getNumSubstitutedLevels() == 0)
-    return ConstrExpr;
-
-  Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/false);
-  std::optional<Sema::CXXThisScopeRAII> ThisScope;
-  if (auto *RD = dyn_cast<CXXRecordDecl>(ND->getDeclContext()))
-    ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
-  ExprResult SubstConstr =
-      S.SubstConstraintExpr(const_cast<clang::Expr *>(ConstrExpr), MLTAL);
-  if (SFINAE.hasErrorOccurred() || !SubstConstr.isUsable())
-    return nullptr;
-  return SubstConstr.get();
-}
-
 bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old,
                                          const Expr *OldConstr,
                                          const NamedDecl *New,
                                          const Expr *NewConstr) {
-  if (OldConstr == NewConstr)
-    return true;
   if (Old && New && Old != New) {
-    if (const Expr *SubstConstr =
-            SubstituteConstraintExpression(*this, Old, OldConstr))
-      OldConstr = SubstConstr;
-    else
-      return false;
-    if (const Expr *SubstConstr =
-            SubstituteConstraintExpression(*this, New, NewConstr))
-      NewConstr = SubstConstr;
-    else
-      return false;
+    unsigned Depth1 = CalculateTemplateDepthForConstraints(
+        *this, Old);
+    unsigned Depth2 = CalculateTemplateDepthForConstraints(
+        *this, New);
+
+    // Adjust the 'shallowest' verison of this to increase the depth to match
+    // the 'other'.
+    if (Depth2 > Depth1) {
+      OldConstr = AdjustConstraintDepth(*this, Depth2 - Depth1)
+                      .TransformExpr(const_cast<Expr *>(OldConstr))
+                      .get();
+    } else if (Depth1 > Depth2) {
+      NewConstr = AdjustConstraintDepth(*this, Depth1 - Depth2)
+                      .TransformExpr(const_cast<Expr *>(NewConstr))
+                      .get();
+    }
   }
 
   llvm::FoldingSetNodeID ID1, ID2;

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 135bf8053a964..29d6bd852ec67 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1297,7 +1297,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
     // We check the return type and template parameter lists for function
     // templates first; the remaining checks follow.
     bool SameTemplateParameterList = TemplateParameterListsAreEqual(
-        NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate,
+        NewTemplate->getTemplateParameters(),
         OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch);
     bool SameReturnType = Context.hasSameType(Old->getDeclaredReturnType(),
                                               New->getDeclaredReturnType());

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index db72b8b3089e6..b249d389bb677 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2882,7 +2882,7 @@ CheckDeducedArgumentConstraints(Sema &S, TemplateDeclT *Template,
   // not class-scope explicit specialization, so replace with Deduced Args
   // instead of adding to inner-most.
   if (NeedsReplacement)
-    MLTAL.replaceInnermostTemplateArguments(Template, CanonicalDeducedArgs);
+    MLTAL.replaceInnermostTemplateArguments(CanonicalDeducedArgs);
 
   if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL,
                                     Info.getLocation(),

diff  --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 445d8d7e1fbb6..1582a5c4b6e44 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -132,38 +132,6 @@ HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl *TTP,
   return Response::Done();
 }
 
-Response HandlePartialClassTemplateSpec(
-    const ClassTemplatePartialSpecializationDecl *PartialClassTemplSpec,
-    MultiLevelTemplateArgumentList &Result, bool SkipForSpecialization) {
-  // We don't want the arguments from the Partial Specialization, since
-  // anything instantiating here cannot access the arguments from the
-  // specialized template anyway, so any substitution we would do with these
-  // partially specialized arguments would 'wrong' and confuse constraint
-  // instantiation. We only do this in the case of a constraint check, since
-  // code elsewhere actually uses these and replaces them later with what
-  // they mean.
-  // If we know this is the 'top level', we can replace this with an
-  // OuterRetainedLevel, else we have to generate a set of identity arguments.
-
-  // If this is the top-level template entity, we can just add a retained level
-  // and be done.
-  if (!PartialClassTemplSpec->getTemplateDepth()) {
-    if (!SkipForSpecialization)
-      Result.addOuterRetainedLevel();
-    return Response::Done();
-  }
-
-  // Else, we can replace this with an 'empty' level, and the checking will just
-  // alter the 'depth', since this we don't have the 'Index' for this level.
-  if (!SkipForSpecialization)
-    Result.addOuterTemplateArguments(
-        const_cast<ClassTemplatePartialSpecializationDecl *>(
-            PartialClassTemplSpec),
-        {}, /*Final=*/false);
-
-  return Response::UseNextDecl(PartialClassTemplSpec);
-}
-
 // Add template arguments from a class template instantiation.
 Response
 HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
@@ -241,21 +209,6 @@ Response HandleFunction(const FunctionDecl *Function,
   return Response::UseNextDecl(Function);
 }
 
-Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
-                                    MultiLevelTemplateArgumentList &Result) {
-  if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) {
-    NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier();
-    const Type *Ty;
-    const TemplateSpecializationType *TSTy;
-    if (NNS && (Ty = NNS->getAsType()) &&
-        (TSTy = Ty->getAs<TemplateSpecializationType>()))
-      Result.addOuterTemplateArguments(const_cast<FunctionTemplateDecl *>(FTD),
-                                       TSTy->template_arguments(),
-                                       /*Final=*/false);
-  }
-  return Response::ChangeDecl(FTD->getLexicalDeclContext());
-}
-
 Response HandleRecordDecl(const CXXRecordDecl *Rec,
                           MultiLevelTemplateArgumentList &Result,
                           ASTContext &Context,
@@ -266,10 +219,15 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
         "Outer template not instantiated?");
     if (ClassTemplate->isMemberSpecialization())
       return Response::Done();
-    if (ForConstraintInstantiation)
+    if (ForConstraintInstantiation) {
+      QualType RecordType = Context.getTypeDeclType(Rec);
+      QualType Injected = cast<InjectedClassNameType>(RecordType)
+                              ->getInjectedSpecializationType();
+      const auto *InjectedType = cast<TemplateSpecializationType>(Injected);
       Result.addOuterTemplateArguments(const_cast<CXXRecordDecl *>(Rec),
-                                       ClassTemplate->getInjectedTemplateArgs(),
+                                       InjectedType->template_arguments(),
                                        /*Final=*/false);
+    }
   }
 
   bool IsFriend = Rec->getFriendObjectKind() ||
@@ -337,23 +295,18 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
   // Accumulate the set of template argument lists in this structure.
   MultiLevelTemplateArgumentList Result;
 
-  using namespace TemplateInstArgsHelpers;
-  const Decl *CurDecl = ND;
-  if (Innermost) {
+  if (Innermost)
     Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND),
                                      Innermost->asArray(), Final);
-    CurDecl = Response::UseNextDecl(ND).NextDecl;
-  }
+
+  const Decl *CurDecl = ND;
 
   while (!CurDecl->isFileContextDecl()) {
+    using namespace TemplateInstArgsHelpers;
     Response R;
     if (const auto *VarTemplSpec =
             dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
       R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);
-    } else if (const auto *PartialClassTemplSpec =
-                   dyn_cast<ClassTemplatePartialSpecializationDecl>(CurDecl)) {
-      R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,
-                                         SkipForSpecialization);
     } else if (const auto *ClassTemplSpec =
                    dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
       R = HandleClassTemplateSpec(ClassTemplSpec, Result,
@@ -366,8 +319,6 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
     } else if (const auto *CSD =
                    dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
       R = HandleImplicitConceptSpecializationDecl(CSD, Result);
-    } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(CurDecl)) {
-      R = HandleFunctionTemplateDecl(FTD, Result);
     } else if (!isa<DeclContext>(CurDecl)) {
       R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
       if (CurDecl->getDeclContext()->isTranslationUnit()) {

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3c78343eb861b..e74b2b2e868ee 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1654,12 +1654,33 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
         << QualifierLoc.getSourceRange();
       return nullptr;
     }
+
+    if (PrevClassTemplate) {
+      const ClassTemplateDecl *MostRecentPrevCT =
+          PrevClassTemplate->getMostRecentDecl();
+      TemplateParameterList *PrevParams =
+          MostRecentPrevCT->getTemplateParameters();
+
+      // Make sure the parameter lists match.
+      if (!SemaRef.TemplateParameterListsAreEqual(
+              D->getTemplatedDecl(), InstParams,
+              MostRecentPrevCT->getTemplatedDecl(), PrevParams, true,
+              Sema::TPL_TemplateMatch))
+        return nullptr;
+
+      // Do some additional validation, then merge default arguments
+      // from the existing declarations.
+      if (SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
+                                             Sema::TPC_ClassTemplate))
+        return nullptr;
+    }
   }
 
   CXXRecordDecl *RecordInst = CXXRecordDecl::Create(
       SemaRef.Context, Pattern->getTagKind(), DC, Pattern->getBeginLoc(),
       Pattern->getLocation(), Pattern->getIdentifier(), PrevDecl,
       /*DelayTypeCreation=*/true);
+
   if (QualifierLoc)
     RecordInst->setQualifierInfo(QualifierLoc);
 
@@ -1669,38 +1690,16 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   ClassTemplateDecl *Inst
     = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
                                 D->getIdentifier(), InstParams, RecordInst);
+  assert(!(isFriend && Owner->isDependentContext()));
+  Inst->setPreviousDecl(PrevClassTemplate);
+
   RecordInst->setDescribedClassTemplate(Inst);
 
   if (isFriend) {
-    assert(!Owner->isDependentContext());
-    Inst->setLexicalDeclContext(Owner);
-    RecordInst->setLexicalDeclContext(Owner);
-
-    if (PrevClassTemplate) {
-      Inst->setCommonPtr(PrevClassTemplate->getCommonPtr());
-      RecordInst->setTypeForDecl(
-          PrevClassTemplate->getTemplatedDecl()->getTypeForDecl());
-      const ClassTemplateDecl *MostRecentPrevCT =
-          PrevClassTemplate->getMostRecentDecl();
-      TemplateParameterList *PrevParams =
-          MostRecentPrevCT->getTemplateParameters();
-
-      // Make sure the parameter lists match.
-      if (!SemaRef.TemplateParameterListsAreEqual(
-              RecordInst, InstParams, MostRecentPrevCT->getTemplatedDecl(),
-              PrevParams, true, Sema::TPL_TemplateMatch))
-        return nullptr;
-
-      // Do some additional validation, then merge default arguments
-      // from the existing declarations.
-      if (SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
-                                             Sema::TPC_ClassTemplate))
-        return nullptr;
-
+    if (PrevClassTemplate)
       Inst->setAccess(PrevClassTemplate->getAccess());
-    } else {
+    else
       Inst->setAccess(D->getAccess());
-    }
 
     Inst->setObjectOfFriendDecl();
     // TODO: do we want to track the instantiation progeny of this
@@ -1711,15 +1710,15 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
       Inst->setInstantiatedFromMemberTemplate(D);
   }
 
-  Inst->setPreviousDecl(PrevClassTemplate);
-
   // Trigger creation of the type for the instantiation.
-  SemaRef.Context.getInjectedClassNameType(
-      RecordInst, Inst->getInjectedClassNameSpecialization());
+  SemaRef.Context.getInjectedClassNameType(RecordInst,
+                                    Inst->getInjectedClassNameSpecialization());
 
   // Finish handling of friends.
   if (isFriend) {
     DC->makeDeclVisibleInContext(Inst);
+    Inst->setLexicalDeclContext(Owner);
+    RecordInst->setLexicalDeclContext(Owner);
     return Inst;
   }
 

diff  --git a/clang/test/SemaTemplate/concepts-friends.cpp b/clang/test/SemaTemplate/concepts-friends.cpp
index 5c4609520a3c7..3a9b308a65c5d 100644
--- a/clang/test/SemaTemplate/concepts-friends.cpp
+++ b/clang/test/SemaTemplate/concepts-friends.cpp
@@ -441,27 +441,3 @@ namespace NTTP {
     templ_func<1>(u2);
   }
 }
-
-
-namespace FriendOfFriend {
-
-template <typename>
-concept Concept = true;
-
-template <Concept> class FriendOfBar;
-
-template <Concept> class Bar {
-  template <Concept> friend class FriendOfBar;
-};
-
-Bar<void> BarInstance;
-
-namespace internal {
-void FriendOfFoo(FriendOfBar<void>);
-}
-
-template <Concept> class Foo {
-  friend void internal::FriendOfFoo(FriendOfBar<void>);
-};
-
-} // namespace FriendOfFriend

diff  --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
index 00c8097d575d0..222b78e0d22f7 100644
--- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
+++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp
@@ -127,220 +127,3 @@ static_assert(S<XY>::specialization("str") == SPECIALIZATION_CONCEPT);
 static_assert(S<int>::specialization("str") == SPECIALIZATION_REQUIRES);
 
 } // namespace multiple_template_parameter_lists
-
-static constexpr int CONSTRAINED_METHOD_1 = 1;
-static constexpr int CONSTRAINED_METHOD_2 = 2;
-
-namespace constrained_members {
-
-template <int>
-struct S {
-  template <Concept C>
-  static constexpr int constrained_method();
-};
-
-template <>
-template <Concept C>
-constexpr int S<1>::constrained_method() { return CONSTRAINED_METHOD_1; }
-
-template <>
-template <Concept C>
-constexpr int S<2>::constrained_method() { return CONSTRAINED_METHOD_2; }
-
-static_assert(S<1>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
-static_assert(S<2>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
-
-
-template <class T1, class T2>
-concept ConceptT1T2 = true;
-
-template<typename T3>
-struct S12 {
-  template<ConceptT1T2<T3> T4>
-  static constexpr int constrained_method();
-};
-
-template<>
-template<ConceptT1T2<int> T5>
-constexpr int S12<int>::constrained_method() { return CONSTRAINED_METHOD_1; }
-
-template<>
-template<ConceptT1T2<double> T5>
-constexpr int S12<double>::constrained_method() { return CONSTRAINED_METHOD_2; }
-
-static_assert(S12<int>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
-static_assert(S12<double>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
-
-} // namespace constrained members
-
-namespace constrained_members_of_nested_types {
-
-template <int>
-struct S {
-  struct Inner0 {
-    struct Inner1 {
-      template <Concept C>
-      static constexpr int constrained_method();
-    };
-  };
-};
-
-template <>
-template <Concept C>
-constexpr int S<1>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
-
-template <>
-template <Concept C>
-constexpr int S<2>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
-
-static_assert(S<1>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
-static_assert(S<2>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
-
-
-template <class T1, class T2>
-concept ConceptT1T2 = true;
-
-template<typename T3>
-struct S12 {
-  struct Inner0 {
-    struct Inner1 {
-      template<ConceptT1T2<T3> T4>
-      static constexpr int constrained_method();
-    };
-  };
-};
-
-template<>
-template<ConceptT1T2<int> T5>
-constexpr int S12<int>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
-
-template<>
-template<ConceptT1T2<double> T5>
-constexpr int S12<double>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
-
-static_assert(S12<int>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
-static_assert(S12<double>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
-
-} // namespace constrained_members_of_nested_types
-
-namespace constrained_member_sfinae {
-
-template<int N> struct S {
-  template<class T>
-  static constexpr int constrained_method() requires (sizeof(int[N * 1073741824 + 4]) == 16) {
-    return CONSTRAINED_METHOD_1;
-  }
-
-  template<class T>
-  static constexpr int constrained_method() requires (sizeof(int[N]) == 16);
-};
-
-template<>
-template<typename T>
-constexpr int S<4>::constrained_method() requires (sizeof(int[4]) == 16) {
-  return CONSTRAINED_METHOD_2;
-}
-
-// Verify that there is no amiguity in this case.
-static_assert(S<4>::constrained_method<double>() == CONSTRAINED_METHOD_2);
-
-} // namespace constrained_member_sfinae
-
-namespace requires_expression_references_members {
-
-void accept1(int x);
-void accept2(XY xy);
-
-template <class T> struct S {
-  T Field = T();
-
-  constexpr int constrained_method()
-      requires requires { accept1(Field); };
-
-  constexpr int constrained_method()
-      requires requires { accept2(Field); };
-};
-
-template <class T>
-constexpr int S<T>::constrained_method()
-  requires requires { accept1(Field); } {
-  return CONSTRAINED_METHOD_1;
-}
-
-template <class T>
-constexpr int S<T>::constrained_method()
-  requires requires { accept2(Field); } {
-  return CONSTRAINED_METHOD_2;
-}
-
-static_assert(S<int>().constrained_method() == CONSTRAINED_METHOD_1);
-static_assert(S<XY>().constrained_method() == CONSTRAINED_METHOD_2);
-
-} // namespace requires_expression_references_members
-
-namespace GH60231 {
-
-template<typename T0> concept C = true;
-
-template <typename T1>
-struct S {
-  template <typename F1> requires C<S<T1>>
-  void foo1(F1 f);
-
-  template <typename F2>
-  void foo2(F2 f) requires C<S<T1>>;
-
-  template <typename F3> requires C<F3>
-  void foo3(F3 f);
-};
-
-template <typename T2>
-template <typename F4> requires C<S<T2>>
-void S<T2>::foo1(F4 f) {}
-
-template <typename T3>
-template <typename F5>
-void S<T3>::foo2(F5 f) requires C<S<T3>> {}
-
-template <typename T4>
-template <typename F6> requires C<F6>
-void S<T4>::foo3(F6 f) {}
-
-} // namespace GH60231
-
-namespace GH62003 {
-
-template <typename T0> concept Concept = true;
-
-template <class T1>
-struct S1 {
-  template <Concept C1>
-  static constexpr int foo();
-};
-template <class T2>
-template <Concept C2>
-constexpr int S1<T2>::foo() { return 1; }
-
-template <Concept C3>
-struct S2 {
-  template <class T3>
-  static constexpr int foo();
-};
-template <Concept C4>
-template <class T4>
-constexpr int S2<C4>::foo() { return 2; }
-
-template <Concept C5>
-struct S3 {
-  template <Concept C6>
-  static constexpr int foo();
-};
-template <Concept C7>
-template <Concept C8>
-constexpr int S3<C7>::foo() { return 3; }
-
-static_assert(S1<int>::foo<int>() == 1);
-static_assert(S2<int>::foo<int>() == 2);
-static_assert(S3<int>::foo<int>() == 3);
-
-} // namespace GH62003

diff  --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 80e233ad9bef3..d28c2b22bd045 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -816,101 +816,3 @@ static_assert(Parent<int>::TakesBinary<int, 0>::i == 0);
 static_assert(Parent<int>::TakesBinary<int, 0ULL>::i == 0);
 }
 
-namespace TemplateInsideNonTemplateClass {
-template<typename T, typename U> concept C = true;
-
-template<typename T> auto L = []<C<T> U>() {};
-
-struct Q {
-  template<C<int> U> friend constexpr auto decltype(L<int>)::operator()() const;
-};
-
-template <class T>
-concept C1 = false;
-
-struct Foo {
-  template <typename>
-  struct Bar {};
-
-  template <typename T>
-    requires(C1<T>)
-  struct Bar<T>;
-};
-
-Foo::Bar<int> BarInstance;
-} // namespace TemplateInsideNonTemplateClass
-
-namespace GH61959 {
-template <typename T0>
-concept C = (sizeof(T0) >= 4);
-
-template<typename...>
-struct Orig { };
-
-template<typename T>
-struct Orig<T> {
-  template<typename> requires C<T>
-  void f() { }
-
-  template<typename> requires true
-  void f() { }
-};
-
-template <typename...> struct Mod {};
-
-template <typename T1, typename T2>
-struct Mod<T1, T2> {
-  template <typename> requires C<T1>
-  constexpr static int f() { return 1; }
-
-  template <typename> requires C<T2>
-  constexpr static int f() { return 2; }
-};
-
-static_assert(Mod<int, char>::f<double>() == 1);
-static_assert(Mod<char, int>::f<double>() == 2);
-
-template<typename T>
-struct Outer {
-  template<typename ...>
-  struct Inner {};
-
-  template<typename U>
-  struct Inner<U> {
-    template<typename V>
-    void foo()  requires C<U> && C<T> && C<V>{}
-    template<typename V>
-    void foo()  requires true{}
-  };
-};
-
-void bar() {
-  Outer<int>::Inner<float> I;
-  I.foo<char>();
-}
-} // namespace GH61959
-
-
-namespace TemplateInsideTemplateInsideTemplate {
-template<typename T>
-concept C1 = false;
-
-template <unsigned I0>
-struct W0 {
-  template <unsigned I1>
-  struct W1 {
-    template <typename T>
-    struct F {
-      enum { value = 1 };
-    };
-
-    template <typename T>
-      requires C1<T>
-    struct F<T> {
-      enum { value = 2 };
-    };
-  };
-};
-
-static_assert(W0<0>::W1<1>::F<int>::value == 1);
-} // TemplateInsideTemplateInsideTemplate


        


More information about the cfe-commits mailing list