diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -588,9 +588,10 @@ ([temp.func.order]p6.2.1 is not implemented, matching GCC). - Implemented `P0857R0 `_, which specifies constrained lambdas and constrained template *template-parameter*\s. - - Do not hide templated base members introduced via using-decl in derived class (useful specially for constrained members). Fixes `GH50886 `_. +- Fixed a crash during template instantiation on a conversion operator during constraint + evaulation. Fixes `GH50891 `_. C++2b Feature Support ^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -7675,6 +7675,26 @@ return; } + if (FunctionTemplate->hasAssociatedConstraints()) { + TemplateDeductionInfo ConstraintInfo(FunctionTemplate->getLocation()); + llvm::SmallVector AC; + FunctionTemplate->getAssociatedConstraints(AC); + for (const Expr *ConstraintExpr : AC) { + Sema::InstantiatingTemplate Inst( + *this, ConstraintExpr->getBeginLoc(), + Sema::InstantiatingTemplate::ConstraintSubstitution{}, + FunctionTemplate, ConstraintInfo, ConstraintExpr->getSourceRange()); + if (Inst.isInvalid() || Inst.isAlreadyInstantiating()) { + OverloadCandidate &Candidate = CandidateSet.addCandidate(); + Candidate.FoundDecl = FoundDecl; + Candidate.Function = FunctionTemplate->getTemplatedDecl(); + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_constraints_not_satisfied; + return; + } + } + } + TemplateDeductionInfo Info(CandidateSet.getLocation()); CXXConversionDecl *Specialization = nullptr; if (TemplateDeductionResult Result diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -764,3 +764,18 @@ __iterator_traits_member_pointer_or_arrow_or_void> f; } }// namespace InheritedFromPartialSpec + +namespace Issue50891 { +template +concept Numeric = + requires(T a) { + foo(a); + }; + +struct Deferred { + friend void foo(Deferred); + template operator TO(); +}; + +static_assert(Numeric); // should not crash clang +} // namespace Issue50891