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/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 6413a48f809ac9..580e759f634956 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 00000000000000..d01a54133f6c39 --- /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/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 00000000000000..b787edb188ed8b --- /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 73459496e4cd9a..98a3f4623098af 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/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 580e759f634956..04cfe5435eb231 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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits