alexander-shaposhnikov created this revision. alexander-shaposhnikov added reviewers: erichkeane, rsmith, aaron.ballman. alexander-shaposhnikov created this object with visibility "All Users". Herald added a project: All. alexander-shaposhnikov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The associated github issue: https://github.com/llvm/llvm-project/issues/61414 It also fixes https://github.com/llvm/llvm-project/issues/49620#issuecomment-1387667143 and https://github.com/llvm/llvm-project/issues/60231 Test plan: 1/ ninja check-all 2/ Bootstrapped Clang passes all the tests Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D146178 Files: clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaTemplate/concepts-out-of-line-def.cpp
Index: clang/test/SemaTemplate/concepts-out-of-line-def.cpp =================================================================== --- clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -127,3 +127,27 @@ static_assert(S<int>::specialization("str") == SPECIALIZATION_REQUIRES); } // namespace multiple_template_parameter_lists + +namespace constrained_members { + +static constexpr int CONSTRAINED_METHOD_1 = 1; +static constexpr int CONSTRAINED_METHOD_2 = 2; + +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); + +} // namespace constrained members Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -1296,9 +1296,11 @@ // // We check the return type and template parameter lists for function // templates first; the remaining checks follow. + bool SameTemplateParameterList = TemplateParameterListsAreEqual( - NewTemplate->getTemplateParameters(), - OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch); + NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate, + OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch, + SourceLocation(), false /* PartialOrdering */); bool SameReturnType = Context.hasSameType(Old->getDeclaredReturnType(), New->getDeclaredReturnType()); // FIXME(GH58571): Match template parameter list even for non-constrained Index: clang/lib/Sema/SemaConcept.cpp =================================================================== --- clang/lib/Sema/SemaConcept.cpp +++ clang/lib/Sema/SemaConcept.cpp @@ -733,12 +733,19 @@ } namespace { - class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> { +class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> { +public: + enum DepthAdjustmentKind { Diff, Value }; + +private: unsigned TemplateDepth = 0; - public: + DepthAdjustmentKind Kind; + +public: using inherited = TreeTransform<AdjustConstraintDepth>; - AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth) - : inherited(SemaRef), TemplateDepth(TemplateDepth) {} + AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth, + DepthAdjustmentKind Kind) + : inherited(SemaRef), TemplateDepth(TemplateDepth), Kind(Kind) {} using inherited::TransformTemplateTypeParmType; QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB, @@ -751,13 +758,13 @@ TransformDecl(TL.getNameLoc(), OldTTPDecl)); QualType Result = getSema().Context.getTemplateTypeParmType( - T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(), - NewTTPDecl); + Kind == Diff ? T->getDepth() + TemplateDepth : TemplateDepth, + T->getIndex(), T->isParameterPack(), NewTTPDecl); TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); return Result; } - }; +}; } // namespace bool Sema::AreConstraintExpressionsEqual(const NamedDecl *Old, @@ -765,22 +772,19 @@ const NamedDecl *New, const Expr *NewConstr) { if (Old && New && Old != New) { - 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(); - } + unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, Old); + unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, New); + unsigned MaxDepth = std::max(Depth1, Depth2); + // The depths calculated for the declarations can be equal but they still + // may differ from the depths of types inside OldConstr and NewConstr. + OldConstr = + AdjustConstraintDepth(*this, MaxDepth, AdjustConstraintDepth::Value) + .TransformExpr(const_cast<Expr *>(OldConstr)) + .get(); + NewConstr = + AdjustConstraintDepth(*this, MaxDepth, AdjustConstraintDepth::Value) + .TransformExpr(const_cast<Expr *>(NewConstr)) + .get(); } llvm::FoldingSetNodeID ID1, ID2; @@ -1454,11 +1458,11 @@ for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) { if (Depth2 > Depth1) { - AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1) + AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1, AdjustConstraintDepth::Diff) .TransformExpr(const_cast<Expr *>(AC1[I])) .get(); } else if (Depth1 > Depth2) { - AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2) + AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2, AdjustConstraintDepth::Diff) .TransformExpr(const_cast<Expr *>(AC2[I])) .get(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits