diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -211,16 +211,16 @@ - Correctly set expression evaluation context as 'immediate function context' in consteval functions. This fixes `GH51182 ` - - Fixes an assert crash caused by looking up missing vtable information on ``consteval`` virtual functions. Fixes `GH55065 `_. - - Skip rebuilding lambda expressions in arguments of immediate invocations. This fixes `GH56183 `_, `GH51695 `_, `GH50455 `_, `GH54872 `_, `GH54587 `_. +- 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/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4020,8 +4020,14 @@ // // Note: SecondStepOfCopyInit is only ever true in this case when // evaluating whether to produce a C++98 compatibility warning. + // + // The last check avoids an infinite template expansion loop in + // requirements checking by skipping the conversion functions check. if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && - !SecondStepOfCopyInit) { + !SecondStepOfCopyInit && + (S.CodeSynthesisContexts.empty() || + S.CodeSynthesisContexts.back().Kind != + Sema::CodeSynthesisContext::RequirementInstantiation)) { Expr *Initializer = Args[0]; auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl(); if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { 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 @@ -256,3 +256,20 @@ C auto **&j2 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} C auto **&&j3 = g(); // expected-error {{deduced type 'int' does not satisfy 'C'}} } + +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