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 <congcongcai0...@163.com> Date: Thu, 18 Jan 2024 23:12:23 +0800 Subject: [PATCH 1/4] [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 6413a48f809ac..580e759f63495 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 0000000000000..d01a54133f6c3 --- /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 <congcongcai0...@163.com> Date: Sat, 20 Jan 2024 13:40:12 +0800 Subject: [PATCH 2/4] 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 0000000000000..b787edb188ed8 --- /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 73459496e4cd9..98a3f4623098a 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 <congcongcai0...@163.com> Date: Sat, 20 Jan 2024 13:56:10 +0800 Subject: [PATCH 3/4] 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 580e759f63495..04cfe5435eb23 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); >From 6cda60056a26f8d489fce1146775b8be8e1fde18 Mon Sep 17 00:00:00 2001 From: Congcong Cai <congcongcai0...@163.com> Date: Tue, 6 Feb 2024 22:18:43 +0800 Subject: [PATCH 4/4] add test --- clang/lib/Sema/SemaExpr.cpp | 10 +++------ ...uires-expression-with-capture-variable.cpp | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index da168d1676943..88333b5e66fc5 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -19706,12 +19706,6 @@ 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, @@ -19727,7 +19721,9 @@ bool Sema::tryCaptureVariable( (!BuildAndDiagnose || VarDC == CurContext)) return true; - DeclContext *DC = ignoreReuquiresBodyDecl(CurContext); + DeclContext *DC = isa_and_present<RequiresExprBodyDecl>(CurContext) + ? CurContext->getParent() + : CurContext; const auto *VD = dyn_cast<VarDecl>(Var); if (VD) { diff --git a/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp index d01a54133f6c3..5f3d0fc90da5b 100644 --- a/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp +++ b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp @@ -2,24 +2,33 @@ // expected-no-diagnostics -auto GH69307_Func_1() { +auto GH69307_correct() { + constexpr auto b = 1; + // no need to capture + return [](auto c) -> int + requires requires { b + c; } + { return 1; }; +}; +auto GH69307_correct_ret = GH69307_correct()(1); + +auto GH69307_func() { constexpr auto b = 1; return [&](auto c) -> int requires requires { b + c; } { return 1; }; }; -auto GH69307_Func_Ret = GH69307_Func_1()(1); +auto GH69307_func_ret = GH69307_func()(1); -auto GH69307_Lambda_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_1_ret = GH69307_lambda_1()(1); -auto GH69307_Lambda_2 = [](auto c) { +auto GH69307_lambda_2 = [](auto c) { return [&]() -> int requires requires { c; } { return 1; }; }; -auto GH69307_Lambda_2_Ret = GH69307_Lambda_2(1)(); +auto GH69307_lambda_2_ret = GH69307_lambda_2(1)(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits