Skip to content

Commit 3e69e5a

Browse files
zyn0217cor3ntin
andauthored
[Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (#83420)
This fixes the case shown by #64808 (comment). Similar to f9caa12, we have some calls to constraint checking for a lambda's conversion function while determining the conversion sequence. This patch addresses the problem where the requires-expression within such a lambda references to a Decl outside of the lambda by adding these Decls to the current instantiation scope. I'm abusing the flag `ForOverloadResolution` of CheckFunctionConstraints, which is actually meant to consider the Decls from parent DeclContexts. --------- Co-authored-by: cor3ntin <[email protected]>
1 parent 5a3cc7b commit 3e69e5a

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ Bug Fixes to C++ Support
387387
Fixes (#GH80997)
388388
- Fix an issue where missing set friend declaration in template class instantiation.
389389
Fixes (#GH84368).
390+
- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the
391+
expression references to an entity declared outside of the lambda. (#GH64808)
390392

391393
Bug Fixes to AST Handling
392394
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaConcept.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,11 +692,15 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
692692
// A lambda conversion operator has the same constraints as the call operator
693693
// and constraints checking relies on whether we are in a lambda call operator
694694
// (and may refer to its parameters), so check the call operator instead.
695+
// Note that the declarations outside of the lambda should also be
696+
// considered. Turning on the 'ForOverloadResolution' flag results in the
697+
// LocalInstantiationScope not looking into its parents, but we can still
698+
// access Decls from the parents while building a lambda RAII scope later.
695699
if (const auto *MD = dyn_cast<CXXConversionDecl>(FD);
696700
MD && isLambdaConversionOperator(const_cast<CXXConversionDecl *>(MD)))
697701
return CheckFunctionConstraints(MD->getParent()->getLambdaCallOperator(),
698702
Satisfaction, UsageLoc,
699-
ForOverloadResolution);
703+
/*ShouldAddDeclsFromParentScope=*/true);
700704

701705
DeclContext *CtxToSave = const_cast<FunctionDecl *>(FD);
702706

clang/test/SemaTemplate/concepts.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,3 +1085,32 @@ template void Struct<void>::bar<>();
10851085
template int Struct<void>::field<1, 2>;
10861086

10871087
}
1088+
1089+
namespace GH64808 {
1090+
1091+
template <class T> struct basic_sender {
1092+
T func;
1093+
basic_sender(T) : func(T()) {}
1094+
};
1095+
1096+
auto a = basic_sender{[](auto... __captures) {
1097+
return []() // #note-a-1
1098+
requires((__captures, ...), false) // #note-a-2
1099+
{};
1100+
}()};
1101+
1102+
auto b = basic_sender{[](auto... __captures) {
1103+
return []()
1104+
requires([](int, double) { return true; }(decltype(__captures)()...))
1105+
{};
1106+
}(1, 2.33)};
1107+
1108+
void foo() {
1109+
a.func();
1110+
// expected-error@-1{{no matching function for call}}
1111+
// expected-note@#note-a-1{{constraints not satisfied}}
1112+
// expected-note@#note-a-2{{evaluated to false}}
1113+
b.func();
1114+
}
1115+
1116+
} // namespace GH64808

0 commit comments

Comments
 (0)