diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1ae35e6881d2f..93cc5291e2391 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -387,6 +387,8 @@ Bug Fixes to C++ Support Fixes (#GH80997) - Fix an issue where missing set friend declaration in template class instantiation. Fixes (#GH84368). +- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the + expression references to an entity declared outside of the lambda. (#GH64808) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index a8e387e35fb4c..1c546e9f5894f 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -692,11 +692,15 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, // A lambda conversion operator has the same constraints as the call operator // and constraints checking relies on whether we are in a lambda call operator // (and may refer to its parameters), so check the call operator instead. + // Note that the declarations outside of the lambda should also be + // considered. Turning on the 'ForOverloadResolution' flag results in the + // LocalInstantiationScope not looking into its parents, but we can still + // access Decls from the parents while building a lambda RAII scope later. if (const auto *MD = dyn_cast(FD); MD && isLambdaConversionOperator(const_cast(MD))) return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(), Satisfaction, UsageLoc, - ForOverloadResolution); + /*ShouldAddDeclsFromParentScope=*/true); DeclContext *CtxToSave = const_cast(FD); diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index bac209a28da91..b7ea0d003a52d 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1085,3 +1085,32 @@ template void Struct::bar<>(); template int Struct::field<1, 2>; } + +namespace GH64808 { + +template struct basic_sender { + T func; + basic_sender(T) : func(T()) {} +}; + +auto a = basic_sender{[](auto... __captures) { + return []() // #note-a-1 + requires((__captures, ...), false) // #note-a-2 + {}; +}()}; + +auto b = basic_sender{[](auto... __captures) { + return []() + requires([](int, double) { return true; }(decltype(__captures)()...)) + {}; +}(1, 2.33)}; + +void foo() { + a.func(); + // expected-error@-1{{no matching function for call}} + // expected-note@#note-a-1{{constraints not satisfied}} + // expected-note@#note-a-2{{evaluated to false}} + b.func(); +} + +} // namespace GH64808