https://github.com/puremourning updated https://github.com/llvm/llvm-project/pull/74661
>From cdd9b653de7aed3d54b5ac6c98fc943183509278 Mon Sep 17 00:00:00 2001 From: Ben Jackson <puremourn...@gmail.com> Date: Wed, 6 Dec 2023 21:59:21 +0000 Subject: [PATCH] Crash when referencing capture in static lambda The constant evaluator could try to reference a lambda capture in a static lambda call operator. Static lambdas can't have captures, so we simply abort. Either the lambda needs to be made non-static, or the capture (and reference to it) need to be removed. --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/lib/AST/ExprConstant.cpp | 14 ++++++++++++-- clang/test/Parser/cxx2b-lambdas.cpp | 12 ++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1fbd332f74057f..0ff8cd23b9426a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -848,6 +848,10 @@ Miscellaneous Clang Crashes Fixed `Issue 41302 <https://github.com/llvm/llvm-project/issues/41302>`_ - Fixed a crash when ``-ast-dump=json`` was used for code using class template deduction guides. +- Fixed a crash when a lambda marked as ``static`` referenced a captured + variable in an expression. + `Issue 74608 <https://github.com/llvm/llvm-project/issues/74608>`_ + OpenACC Specific Changes ------------------------ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 986302e1fd225f..41cf9443a64818 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8492,14 +8492,24 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { return false; if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) { + const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee); + + // Static lambda function call operators can't have captures. We already + // diagnosed this, so bail out here. + if (MD->isStatic()) { + assert(Info.CurrentCall->This == nullptr && + "This should not be set for a static call operator"); + return false; + } + // Start with 'Result' referring to the complete closure object... - if (auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee); - MD->isExplicitObjectMemberFunction()) { + if (MD->isExplicitObjectMemberFunction()) { APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0)); Result.setFrom(Info.Ctx, *RefValue); } else Result = *Info.CurrentCall->This; + // ... then update it to refer to the field of the closure object // that represents the capture. if (!HandleLValueMember(Info, E, Result, FD)) diff --git a/clang/test/Parser/cxx2b-lambdas.cpp b/clang/test/Parser/cxx2b-lambdas.cpp index bb9ed226afffaf..ad975a17b6e476 100644 --- a/clang/test/Parser/cxx2b-lambdas.cpp +++ b/clang/test/Parser/cxx2b-lambdas.cpp @@ -66,3 +66,15 @@ void static_captures() { } }; } + +constexpr auto static_capture_constexpr() { + char n = 'n'; + return [n] static { return n; }(); // expected-error {{a static lambda cannot have any captures}} +} +static_assert(static_capture_constexpr()); // expected-error {{static assertion expression is not an integral constant expression}} + +constexpr auto capture_constexpr() { + char n = 'n'; + return [n] { return n; }(); +} +static_assert(capture_constexpr()); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits