[clang] [Clang] Fix the order of addInstantiatedParameters in LambdaScopeForCallOperatorInstantiationRAII (PR #97215)

Yupei Liu via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 30 06:16:18 PDT 2024


https://github.com/LYP951018 created https://github.com/llvm/llvm-project/pull/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
```

>From 832e5b29e44e6b8fd14eefeecd96000b187569b4 Mon Sep 17 00:00:00 2001
From: letrec <liuyupei951018 at hotmail.com>
Date: Sun, 30 Jun 2024 21:03:23 +0800
Subject: [PATCH 1/2] Fix the order of addInstantiatedParameters in
 LambdaScopeForCallOperatorInstantiationRAII.

---
 clang/lib/Sema/SemaLambda.cpp               | 39 +++++++++++++--------
 clang/test/SemaTemplate/concepts-lambda.cpp | 14 ++++++++
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index e9476a0c93c5d..c5ed7b1dbfd56 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);
+  }
+}
\ No newline at end of file
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

>From 015088dee066e710af0a9800c4f52b4cc1c062d7 Mon Sep 17 00:00:00 2001
From: letrec <liuyupei951018 at hotmail.com>
Date: Sun, 30 Jun 2024 21:07:43 +0800
Subject: [PATCH 2/2] add empty line

---
 clang/lib/Sema/SemaLambda.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index c5ed7b1dbfd56..b6344f53861f4 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -2407,4 +2407,4 @@ Sema::LambdaScopeForCallOperatorInstantiationRAII::
     SemaRef.addInstantiatedParametersToScope(Inst, Pattern, Scope, MLTAL);
     SemaRef.addInstantiatedLocalVarsToScope(Inst, Pattern, Scope);
   }
-}
\ No newline at end of file
+}



More information about the cfe-commits mailing list