llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Yupei Liu (LYP951018) <details> <summary>Changes</summary> 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 ``` --- Full diff: https://github.com/llvm/llvm-project/pull/97215.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaLambda.cpp (+23-14) - (modified) clang/test/SemaTemplate/concepts-lambda.cpp (+14) ``````````diff diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e9476a0c93c5d..b6344f53861f4 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -2379,23 +2379,32 @@ Sema::LambdaScopeForCallOperatorInstantiationRAII:: SemaRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD)); - FunctionDecl *Pattern = getPatternFunctionDecl(FD); - if (Pattern) { - SemaRef.addInstantiatedCapturesToScope(FD, Pattern, Scope, MLTAL); + FunctionDecl *FDPattern = getPatternFunctionDecl(FD); + if (!FDPattern) + return; - FunctionDecl *ParentFD = FD; - while (ShouldAddDeclsFromParentScope) { + SemaRef.addInstantiatedCapturesToScope(FD, FDPattern, Scope, MLTAL); - ParentFD = - dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(ParentFD)); - Pattern = - dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(Pattern)); + if (!ShouldAddDeclsFromParentScope) + return; - if (!FD || !Pattern) - break; + llvm::SmallVector<std::pair<FunctionDecl *, FunctionDecl *>, 4> + ParentInstantiations; + std::pair<FunctionDecl *, FunctionDecl *> Current = {FDPattern, FD}; + while (true) { + Current.first = dyn_cast<FunctionDecl>( + getLambdaAwareParentOfDeclContext(Current.first)); + Current.second = dyn_cast<FunctionDecl>( + getLambdaAwareParentOfDeclContext(Current.second)); - SemaRef.addInstantiatedParametersToScope(ParentFD, Pattern, Scope, MLTAL); - SemaRef.addInstantiatedLocalVarsToScope(ParentFD, Pattern, Scope); - } + if (!Current.first || !Current.second) + break; + + ParentInstantiations.push_back(Current); + } + + for (const auto &[Pattern, Inst] : llvm::reverse(ParentInstantiations)) { + SemaRef.addInstantiatedParametersToScope(Inst, Pattern, Scope, MLTAL); + SemaRef.addInstantiatedLocalVarsToScope(Inst, Pattern, Scope); } } diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index 280be71284f97..252ef08549a48 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -237,3 +237,17 @@ concept D = []<C T = int>() { return true; }(); D auto x = 0; } // namespace GH93821 + +namespace dependent_param_concept { +template <typename... Ts> void sink(Ts...) {} +void dependent_param() { + auto L = [](auto... x) { + return [](decltype(x)... y) { + return [](int z) + requires requires { sink(y..., z); } + {}; + }; + }; + L(0, 1)(1, 2)(1); +} +} // namespace dependent_param_concept `````````` </details> https://github.com/llvm/llvm-project/pull/97215 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits