[llvm-branch-commits] [clang] release/20.x: [Clang] Fix a lambda pattern comparison mismatch after ecc7e6ce4 (#133863) (PR #134194)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Apr 2 20:48:12 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (llvmbot)
<details>
<summary>Changes</summary>
Backport dcc2182bc
Requested by: @<!-- -->zyn0217
---
Full diff: https://github.com/llvm/llvm-project/pull/134194.diff
3 Files Affected:
- (modified) clang/lib/Sema/SemaConcept.cpp (-69)
- (modified) clang/lib/Sema/SemaLambda.cpp (+68)
- (modified) clang/test/SemaTemplate/concepts-lambda.cpp (+15)
``````````diff
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index a7b609f7f3ce4..8adebccde042c 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -702,75 +702,6 @@ bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
.isInvalid();
}
-bool Sema::addInstantiatedCapturesToScope(
- FunctionDecl *Function, const FunctionDecl *PatternDecl,
- LocalInstantiationScope &Scope,
- const MultiLevelTemplateArgumentList &TemplateArgs) {
- const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
- const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
-
- unsigned Instantiated = 0;
-
- // FIXME: This is a workaround for not having deferred lambda body
- // instantiation.
- // When transforming a lambda's body, if we encounter another call to a
- // nested lambda that contains a constraint expression, we add all of the
- // outer lambda's instantiated captures to the current instantiation scope to
- // facilitate constraint evaluation. However, these captures don't appear in
- // the CXXRecordDecl until after the lambda expression is rebuilt, so we
- // pull them out from the corresponding LSI.
- LambdaScopeInfo *InstantiatingScope = nullptr;
- if (LambdaPattern->capture_size() && !LambdaClass->capture_size()) {
- for (FunctionScopeInfo *Scope : llvm::reverse(FunctionScopes)) {
- auto *LSI = dyn_cast<LambdaScopeInfo>(Scope);
- if (!LSI ||
- LSI->CallOperator->getTemplateInstantiationPattern() != PatternDecl)
- continue;
- InstantiatingScope = LSI;
- break;
- }
- assert(InstantiatingScope);
- }
-
- auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
- unsigned Index) {
- ValueDecl *CapturedVar =
- InstantiatingScope ? InstantiatingScope->Captures[Index].getVariable()
- : LambdaClass->getCapture(Index)->getCapturedVar();
- assert(CapturedVar->isInitCapture());
- Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
- };
-
- for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
- if (!CapturePattern.capturesVariable()) {
- Instantiated++;
- continue;
- }
- ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
-
- if (!CapturedPattern->isInitCapture()) {
- Instantiated++;
- continue;
- }
-
- if (!CapturedPattern->isParameterPack()) {
- AddSingleCapture(CapturedPattern, Instantiated++);
- } else {
- Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- SemaRef.collectUnexpandedParameterPacks(
- dyn_cast<VarDecl>(CapturedPattern)->getInit(), Unexpanded);
- auto NumArgumentsInExpansion =
- getNumArgumentsInExpansionFromUnexpanded(Unexpanded, TemplateArgs);
- if (!NumArgumentsInExpansion)
- continue;
- for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
- AddSingleCapture(CapturedPattern, Instantiated++);
- }
- }
- return false;
-}
-
bool Sema::SetupConstraintScope(
FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
const MultiLevelTemplateArgumentList &MLTAL,
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index ceb32ee15dfa3..981856fbf25a7 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -2389,6 +2389,74 @@ static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) {
return FTD->getTemplatedDecl();
}
+bool Sema::addInstantiatedCapturesToScope(
+ FunctionDecl *Function, const FunctionDecl *PatternDecl,
+ LocalInstantiationScope &Scope,
+ const MultiLevelTemplateArgumentList &TemplateArgs) {
+ const auto *LambdaClass = cast<CXXMethodDecl>(Function)->getParent();
+ const auto *LambdaPattern = cast<CXXMethodDecl>(PatternDecl)->getParent();
+
+ unsigned Instantiated = 0;
+
+ // FIXME: This is a workaround for not having deferred lambda body
+ // instantiation.
+ // When transforming a lambda's body, if we encounter another call to a
+ // nested lambda that contains a constraint expression, we add all of the
+ // outer lambda's instantiated captures to the current instantiation scope to
+ // facilitate constraint evaluation. However, these captures don't appear in
+ // the CXXRecordDecl until after the lambda expression is rebuilt, so we
+ // pull them out from the corresponding LSI.
+ LambdaScopeInfo *InstantiatingScope = nullptr;
+ if (LambdaPattern->capture_size() && !LambdaClass->capture_size()) {
+ for (FunctionScopeInfo *Scope : llvm::reverse(FunctionScopes)) {
+ auto *LSI = dyn_cast<LambdaScopeInfo>(Scope);
+ if (!LSI || getPatternFunctionDecl(LSI->CallOperator) != PatternDecl)
+ continue;
+ InstantiatingScope = LSI;
+ break;
+ }
+ assert(InstantiatingScope);
+ }
+
+ auto AddSingleCapture = [&](const ValueDecl *CapturedPattern,
+ unsigned Index) {
+ ValueDecl *CapturedVar =
+ InstantiatingScope ? InstantiatingScope->Captures[Index].getVariable()
+ : LambdaClass->getCapture(Index)->getCapturedVar();
+ assert(CapturedVar->isInitCapture());
+ Scope.InstantiatedLocal(CapturedPattern, CapturedVar);
+ };
+
+ for (const LambdaCapture &CapturePattern : LambdaPattern->captures()) {
+ if (!CapturePattern.capturesVariable()) {
+ Instantiated++;
+ continue;
+ }
+ ValueDecl *CapturedPattern = CapturePattern.getCapturedVar();
+
+ if (!CapturedPattern->isInitCapture()) {
+ Instantiated++;
+ continue;
+ }
+
+ if (!CapturedPattern->isParameterPack()) {
+ AddSingleCapture(CapturedPattern, Instantiated++);
+ } else {
+ Scope.MakeInstantiatedLocalArgPack(CapturedPattern);
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ SemaRef.collectUnexpandedParameterPacks(
+ dyn_cast<VarDecl>(CapturedPattern)->getInit(), Unexpanded);
+ auto NumArgumentsInExpansion =
+ getNumArgumentsInExpansionFromUnexpanded(Unexpanded, TemplateArgs);
+ if (!NumArgumentsInExpansion)
+ continue;
+ for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg)
+ AddSingleCapture(CapturedPattern, Instantiated++);
+ }
+ }
+ return false;
+}
+
Sema::LambdaScopeForCallOperatorInstantiationRAII::
LambdaScopeForCallOperatorInstantiationRAII(
Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp
index dcb09c76d26b6..1f67c2511e096 100644
--- a/clang/test/SemaTemplate/concepts-lambda.cpp
+++ b/clang/test/SemaTemplate/concepts-lambda.cpp
@@ -325,3 +325,18 @@ template <class> void f() {
template void f<int>();
}
+
+namespace GH133719 {
+
+template <class T>
+constexpr auto f{[] (auto arg) {
+ return [a{arg}] {
+ [] () requires true {}();
+ };
+}};
+
+void foo() {
+ f<int>(0);
+}
+
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/134194
More information about the llvm-branch-commits
mailing list