[clang] Crash when referencing capture in static lambda (#74661)

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
This commit is contained in:
Ben Jackson 2023-12-12 06:30:23 +00:00 committed by GitHub
parent 5d12274646
commit c88d73164a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 2 deletions

View File

@ -870,6 +870,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
------------------------

View File

@ -8514,14 +8514,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))

View File

@ -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());