[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 18:42:18 PDT 2024
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/112177
>From 78657277495bbd1f82faef655c49320a4315272f 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 1/4] [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 | 23 +++++++++++++++++++
4 files changed, 35 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..dd6ac26cf49b94 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 away 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..32f09b38f84e23 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -297,3 +297,26 @@ void __trans_tmp_1() {
}
}
+
+namespace GH47400 {
+
+struct Foo {};
+
+template <int, Foo f> struct Arr {};
+
+template <int> struct S {};
+
+constexpr bool foo() {
+ constexpr Foo f; // f constitutes an ODR-use
+ [&]<int is>() {
+ [&](Arr<is, f>) {}({});
+ }.template operator()<42>();
+
+ constexpr int C = 1;
+ []() {
+ [](S<C>) { }; // ... while C doesn't
+ };
+ return true;
+}
+
+} // namespace GH47400
>From 85b1f38fc34b77b23d10e2ae4124872659bd2573 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 14 Oct 2024 19:20:30 +0800
Subject: [PATCH 2/4] Fix tests
---
clang/test/SemaCXX/lambda-capture-type-deduction.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index 32f09b38f84e23..253d0f429abbed 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -302,20 +302,20 @@ namespace GH47400 {
struct Foo {};
-template <int, Foo f> struct Arr {};
+template <int, Foo> struct Arr {};
template <int> struct S {};
constexpr bool foo() {
- constexpr Foo f; // f constitutes an ODR-use
+ constexpr Foo f;
[&]<int is>() {
- [&](Arr<is, f>) {}({});
+ [&](Arr<is, f>) {}({}); // f constitutes an ODR-use
}.template operator()<42>();
constexpr int C = 1;
- []() {
- [](S<C>) { }; // ... while C doesn't
- };
+ [] {
+ [](S<C>) { }({}); // ... while C doesn't
+ }();
return true;
}
>From 6fe91020f9564b2177ecd8f8a66b6d02ae9c5f4d Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Mon, 14 Oct 2024 19:51:02 +0800
Subject: [PATCH 3/4] Clarify the assertion intents
---
clang/lib/Sema/SemaExpr.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index dd6ac26cf49b94..0075ec86823920 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18852,7 +18852,8 @@ bool Sema::tryCaptureVariable(
LSI && !LSI->AfterParameterList)
--FSIndex;
assert(MaxFunctionScopesIndex <= FSIndex &&
- "FSIndex is larger than the size of function scopes?");
+ "FunctionScopeIndexToStopAt should be no larger than FSIndex into "
+ "FunctionScopes.");
while (FSIndex != MaxFunctionScopesIndex) {
DC = getLambdaAwareParentOfDeclContext(DC);
--FSIndex;
>From 4b78a50b8e5ca98e603e57c5f8b67f62d59bb917 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Tue, 15 Oct 2024 09:38:57 +0800
Subject: [PATCH 4/4] Guard the case FSIndex == 0; remove unnecessary return
value in tests
---
clang/lib/Sema/SemaExpr.cpp | 4 ++--
clang/test/SemaCXX/lambda-capture-type-deduction.cpp | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0075ec86823920..a253cc26d6c60e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18849,10 +18849,10 @@ bool Sema::tryCaptureVariable(
// NOT the lambda but its parent. So move away the current LSI before
// aligning DC and FunctionScopeIndexToStopAt.
if (auto *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[FSIndex]);
- LSI && !LSI->AfterParameterList)
+ FSIndex && LSI && !LSI->AfterParameterList)
--FSIndex;
assert(MaxFunctionScopesIndex <= FSIndex &&
- "FunctionScopeIndexToStopAt should be no larger than FSIndex into "
+ "FunctionScopeIndexToStopAt should be no greater than FSIndex into "
"FunctionScopes.");
while (FSIndex != MaxFunctionScopesIndex) {
DC = getLambdaAwareParentOfDeclContext(DC);
diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
index 253d0f429abbed..a86f3018989927 100644
--- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -306,7 +306,7 @@ template <int, Foo> struct Arr {};
template <int> struct S {};
-constexpr bool foo() {
+constexpr void foo() {
constexpr Foo f;
[&]<int is>() {
[&](Arr<is, f>) {}({}); // f constitutes an ODR-use
@@ -316,7 +316,6 @@ constexpr bool foo() {
[] {
[](S<C>) { }({}); // ... while C doesn't
}();
- return true;
}
} // namespace GH47400
More information about the cfe-commits
mailing list