llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Ben Jackson (puremourning) <details> <summary>Changes</summary> 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. Fixes: https://github.com/llvm/llvm-project/issues/74608 --- Full diff: https://github.com/llvm/llvm-project/pull/74661.diff 2 Files Affected: - (modified) clang/lib/AST/ExprConstant.cpp (+12-2) - (modified) clang/test/Parser/cxx2b-lambdas.cpp (+12) ``````````diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 986302e1fd225f..e806318efd8a5e 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)) { + 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()); `````````` </details> https://github.com/llvm/llvm-project/pull/74661 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits