[clang] [Clang] Fix a DeclContext mismatch when parsing nested lambda parameters (PR #112177)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 02:52:44 PDT 2024


https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/112177

Fixes #47400
Fixes #90896

>From f63455781f466660986c247221de35bb9e35780d Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 14 Oct 2024 17:42:17 +0800
Subject: [PATCH] [Clang] Fix a DeclContext mismatch when parsing nested lambda
 parameters

---
 clang/docs/ReleaseNotes.rst                      |  2 ++
 clang/lib/Sema/SemaExpr.cpp                      |  9 +++++++++
 clang/lib/Sema/SemaExprCXX.cpp                   |  2 +-
 .../SemaCXX/lambda-capture-type-deduction.cpp    | 16 ++++++++++++++++
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8d02cc3eae9fd9..3d6da43cf02f69 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -487,6 +487,8 @@ Bug Fixes to C++ Support
 - Clang now uses the correct set of template argument lists when comparing the constraints of
   out-of-line definitions and member templates explicitly specialized for a given implicit instantiation of
   a class template. (#GH102320)
+- Fixed a bug in lambda captures where ``constexpr`` class-type objects were not properly considered ODR-used in
+  certain situations. (#GH47400), (#GH90896)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f930a21ea870ec..faa4287072d496 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18843,7 +18843,16 @@ bool Sema::tryCaptureVariable(
   // We need to sync up the Declaration Context with the
   // FunctionScopeIndexToStopAt
   if (FunctionScopeIndexToStopAt) {
+    assert(!FunctionScopes.empty() && "No function scopes to stop at?");
     unsigned FSIndex = FunctionScopes.size() - 1;
+    // When we're parsing the lambda parameter list, the current DeclContext is
+    // NOT the lambda but its parent. So move off the current LSI before
+    // aligning DC and FunctionScopeIndexToStopAt.
+    if (auto *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[FSIndex]);
+        LSI && !LSI->AfterParameterList)
+      --FSIndex;
+    assert(MaxFunctionScopesIndex <= FSIndex &&
+           "FSIndex is larger than the size of function scopes?");
     while (FSIndex != MaxFunctionScopesIndex) {
       DC = getLambdaAwareParentOfDeclContext(DC);
       --FSIndex;
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d490452e91c3bb..09ab83dcf21c22 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -8679,7 +8679,7 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
   while (isa_and_nonnull<CapturedDecl>(DC))
     DC = DC->getParent();
   assert(
-      CurrentLSI->CallOperator == DC &&
+      (CurrentLSI->CallOperator == DC || !CurrentLSI->AfterParameterList) &&
       "The current call operator must be synchronized with Sema's CurContext");
 #endif // NDEBUG
 
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index 7bf36a6a9cab73..974cc8f29eb20f 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -297,3 +297,19 @@ void __trans_tmp_1() {
 }
 
 }
+
+namespace GH47400 {
+
+struct Foo {};
+
+template <int, Foo f> struct Arr {};
+
+constexpr bool foo() {
+  constexpr Foo fff;
+  [&]<int is>() {
+    [&](Arr<is, fff>) {}({});
+  }.template operator()<42>();
+  return true;
+}
+
+} // namespace GH47400



More information about the cfe-commits mailing list