Skip to content

Commit 70cd3ed

Browse files
LYP951018aaryanshukla
authored andcommitted
[Clang] Fix the order of addInstantiatedParameters in LambdaScopeForCallOperatorInstantiationRAII (llvm#97215)
Currently, `addInstantiatedParameters` is called from the innermost lambda outward. However, when the function parameters of an inner lambda depend on the function parameters of an outer lambda, it can lead to a crash due to the inability to find a mapping for the instantiated decl. This PR corrects this behavior by calling `addInstantiatedParameters` from the outside in. repro code: https://godbolt.org/z/KbsxWesW6 ```cpp namespace dependent_param_concept { template <typename... Ts> void sink(Ts...) {} void dependent_param() { auto L = [](auto... x) { return [](decltype(x)... y) { // `y` depends on `x` return [](int z) requires requires { sink(y..., z); } {}; }; }; L(0, 1)(1, 2)(1); } } // namespace dependent_param_concept ``` This PR is a prerequisite for implmenting llvm#61426
1 parent 8b3ebcf commit 70cd3ed

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ Bug Fixes to C++ Support
962962
- Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
963963
- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307),
964964
(#GH88081), (#GH89496), (#GH90669) and (#GH91633).
965+
- Fixed a crash in constraint instantiation under nested lambdas with dependent parameters.
965966
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
966967
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
967968
- Fixed a failed assertion when attempting to convert an integer representing the difference

clang/lib/Sema/SemaLambda.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,23 +2383,37 @@ Sema::LambdaScopeForCallOperatorInstantiationRAII::
23832383

23842384
SemaRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD));
23852385

2386-
FunctionDecl *Pattern = getPatternFunctionDecl(FD);
2387-
if (Pattern) {
2388-
SemaRef.addInstantiatedCapturesToScope(FD, Pattern, Scope, MLTAL);
2386+
FunctionDecl *FDPattern = getPatternFunctionDecl(FD);
2387+
if (!FDPattern)
2388+
return;
23892389

2390-
FunctionDecl *ParentFD = FD;
2391-
while (ShouldAddDeclsFromParentScope) {
2390+
SemaRef.addInstantiatedCapturesToScope(FD, FDPattern, Scope, MLTAL);
23922391

2393-
ParentFD =
2394-
dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(ParentFD));
2395-
Pattern =
2396-
dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(Pattern));
2392+
if (!ShouldAddDeclsFromParentScope)
2393+
return;
23972394

2398-
if (!ParentFD || !Pattern)
2399-
break;
2395+
llvm::SmallVector<std::pair<FunctionDecl *, FunctionDecl *>, 4>
2396+
ParentInstantiations;
2397+
while (true) {
2398+
FDPattern =
2399+
dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FDPattern));
2400+
FD = dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FD));
24002401

2401-
SemaRef.addInstantiatedParametersToScope(ParentFD, Pattern, Scope, MLTAL);
2402-
SemaRef.addInstantiatedLocalVarsToScope(ParentFD, Pattern, Scope);
2403-
}
2402+
if (!FDPattern || !FD)
2403+
break;
2404+
2405+
ParentInstantiations.emplace_back(FDPattern, FD);
2406+
}
2407+
2408+
// Add instantiated parameters and local vars to scopes, starting from the
2409+
// outermost lambda to the innermost lambda. This ordering ensures that
2410+
// parameters in inner lambdas can correctly depend on those defined
2411+
// in outer lambdas, e.g. auto L = [](auto... x) {
2412+
// return [](decltype(x)... y) { }; // `y` depends on `x`
2413+
// };
2414+
2415+
for (const auto &[FDPattern, FD] : llvm::reverse(ParentInstantiations)) {
2416+
SemaRef.addInstantiatedParametersToScope(FD, FDPattern, Scope, MLTAL);
2417+
SemaRef.addInstantiatedLocalVarsToScope(FD, FDPattern, Scope);
24042418
}
24052419
}

clang/test/SemaTemplate/concepts-lambda.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,17 @@ concept D = []<C T = int>() { return true; }();
237237
D auto x = 0;
238238

239239
} // namespace GH93821
240+
241+
namespace dependent_param_concept {
242+
template <typename... Ts> void sink(Ts...) {}
243+
void dependent_param() {
244+
auto L = [](auto... x) {
245+
return [](decltype(x)... y) {
246+
return [](int z)
247+
requires requires { sink(y..., z); }
248+
{};
249+
};
250+
};
251+
L(0, 1)(1, 2)(1);
252+
}
253+
} // namespace dependent_param_concept

0 commit comments

Comments
 (0)