Skip to content

Commit

Permalink
[Clang] Fix constant evaluating a captured variable in a lambda (#68090)
Browse files Browse the repository at this point in the history
with an explicit parameter.

We tried to read a pointer to a non-existent `This` APValue when
constant-evaluating an explicit object lambda call operator (the `this`
pointer is never set in explicit object member functions)

Fixes #68070
  • Loading branch information
cor3ntin committed Oct 5, 2023
1 parent b74cfc1 commit 49666ec
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
8 changes: 7 additions & 1 deletion clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8370,7 +8370,13 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {

if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
// Start with 'Result' referring to the complete closure object...
Result = *Info.CurrentCall->This;
if (auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
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))
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,21 @@ consteval void test() {
static_assert(*s == 42);
static_assert((s << 11) == 31);
}

namespace GH68070 {

constexpr auto f = [x = 3]<typename Self>(this Self&& self) {
return x;
};

auto g = [x = 3]<typename Self>(this Self&& self) {
return x;
};

int test() {
constexpr int a = f();
static_assert(a == 3);
return f() + g();
}

}

0 comments on commit 49666ec

Please sign in to comment.