[clang] [clang] reject to capture variable in `RequiresExprBodyDecl` (PR #78598)
Congcong Cai via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 19 21:56:24 PST 2024
https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/78598
>From 8fa3dc43e770025308da47f6aff309fa58c47fc3 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Thu, 18 Jan 2024 23:12:23 +0800
Subject: [PATCH 1/3] [clang] reject to capture variable in
`RequiresExprBodyDecl`
Expression in `RequiresExprBodyDecl` is resolved as constants and should not be captured.
Fixes: #69307, #76593.
---
clang/lib/Sema/SemaExpr.cpp | 21 ++++++++++------
...uires-expression-with-capture-variable.cpp | 25 +++++++++++++++++++
2 files changed, 38 insertions(+), 8 deletions(-)
create mode 100644 clang/test/SemaCXX/requires-expression-with-capture-variable.cpp
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6413a48f809ac9c..580e759f634956b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19704,6 +19704,12 @@ static void buildLambdaCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI,
}
}
+static DeclContext *ignoreReuquiresBodyDecl(DeclContext *DC) {
+ if (isa_and_present<RequiresExprBodyDecl>(DC))
+ return DC->getParent();
+ return DC;
+}
+
bool Sema::tryCaptureVariable(
ValueDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind,
SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType,
@@ -19711,15 +19717,15 @@ bool Sema::tryCaptureVariable(
// An init-capture is notionally from the context surrounding its
// declaration, but its parent DC is the lambda class.
DeclContext *VarDC = Var->getDeclContext();
- DeclContext *DC = CurContext;
-
// tryCaptureVariable is called every time a DeclRef is formed,
// it can therefore have non-negigible impact on performances.
// For local variables and when there is no capturing scope,
// we can bailout early.
- if (CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == DC))
+ if (CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == CurContext))
return true;
+ DeclContext *DC = ignoreReuquiresBodyDecl(CurContext);
+
const auto *VD = dyn_cast<VarDecl>(Var);
if (VD) {
if (VD->isInitCapture())
@@ -19789,11 +19795,10 @@ bool Sema::tryCaptureVariable(
// Only block literals, captured statements, and lambda expressions can
// capture; other scopes don't work.
- DeclContext *ParentDC =
- !IsInScopeDeclarationContext
- ? DC->getParent()
- : getParentOfCapturingContextOrNull(DC, Var, ExprLoc,
- BuildAndDiagnose, *this);
+ DeclContext *ParentDC = IsInScopeDeclarationContext
+ ? getParentOfCapturingContextOrNull(
+ DC, Var, ExprLoc, BuildAndDiagnose, *this)
+ : DC->getParent();
// We need to check for the parent *first* because, if we *have*
// private-captured a global variable, we need to recursively capture it in
// intermediate blocks, lambdas, etc.
diff --git a/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp
new file mode 100644
index 000000000000000..d01a54133f6c39b
--- /dev/null
+++ b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang -fsyntax-only -std=c++20 -Xclang -verify %s
+
+// expected-no-diagnostics
+
+auto GH69307_Func_1() {
+ constexpr auto b = 1;
+ return [&](auto c) -> int
+ requires requires { b + c; }
+ { return 1; };
+};
+auto GH69307_Func_Ret = GH69307_Func_1()(1);
+
+auto GH69307_Lambda_1 = []() {
+ return [&](auto c) -> int
+ requires requires { c; }
+ { return 1; };
+};
+auto GH69307_Lambda_1_Ret = GH69307_Lambda_1()(1);
+
+auto GH69307_Lambda_2 = [](auto c) {
+ return [&]() -> int
+ requires requires { c; }
+ { return 1; };
+};
+auto GH69307_Lambda_2_Ret = GH69307_Lambda_2(1)();
>From a99f16ff51702ff249cdf8a47de0cf24a08f694a Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sat, 20 Jan 2024 13:40:12 +0800
Subject: [PATCH 2/3] another test
---
clang/test/SemaCXX/warn-unused-lambda-capture-cxx20.cpp | 7 +++++++
clang/test/SemaCXX/warn-unused-lambda-capture.cpp | 4 ++++
2 files changed, 11 insertions(+)
create mode 100644 clang/test/SemaCXX/warn-unused-lambda-capture-cxx20.cpp
diff --git a/clang/test/SemaCXX/warn-unused-lambda-capture-cxx20.cpp b/clang/test/SemaCXX/warn-unused-lambda-capture-cxx20.cpp
new file mode 100644
index 000000000000000..b787edb188ed8b5
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-lambda-capture-cxx20.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++20 %s
+
+void test() {
+ int i;
+ auto explicit_by_value_unused_requires = [i] (auto) requires requires { i; } {}; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+ explicit_by_value_unused_requires(1);
+}
diff --git a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
index 73459496e4cd9a7..98a3f4623098af6 100644
--- a/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
+++ b/clang/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -44,6 +44,10 @@ void test() {
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+#if __cplusplus >= 202002L
+ auto explicit_by_value_unused_requires = [i] (auto) requires requires { i; } {}; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+ explicit_by_value_unused_requires(1);
+#endif
auto explicit_by_reference_used = [&i] { i++; };
auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
>From b27d0ac058ca00257c42a3e2598b4701c8ae812d Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Sat, 20 Jan 2024 13:56:10 +0800
Subject: [PATCH 3/3] format
---
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 580e759f634956b..04cfe5435eb231d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19721,7 +19721,8 @@ bool Sema::tryCaptureVariable(
// it can therefore have non-negigible impact on performances.
// For local variables and when there is no capturing scope,
// we can bailout early.
- if (CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == CurContext))
+ if (CapturingFunctionScopes == 0 &&
+ (!BuildAndDiagnose || VarDC == CurContext))
return true;
DeclContext *DC = ignoreReuquiresBodyDecl(CurContext);
More information about the cfe-commits
mailing list