Skip to content

Commit 49666ec

Browse files
authored
[Clang] Fix constant evaluating a captured variable in a lambda (#68090)
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
1 parent b74cfc1 commit 49666ec

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

clang/lib/AST/ExprConstant.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -8370,7 +8370,13 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
83708370

83718371
if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
83728372
// Start with 'Result' referring to the complete closure object...
8373-
Result = *Info.CurrentCall->This;
8373+
if (auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
8374+
MD->isExplicitObjectMemberFunction()) {
8375+
APValue *RefValue =
8376+
Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0));
8377+
Result.setFrom(Info.Ctx, *RefValue);
8378+
} else
8379+
Result = *Info.CurrentCall->This;
83748380
// ... then update it to refer to the field of the closure object
83758381
// that represents the capture.
83768382
if (!HandleLValueMember(Info, E, Result, FD))

clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,21 @@ consteval void test() {
5454
static_assert(*s == 42);
5555
static_assert((s << 11) == 31);
5656
}
57+
58+
namespace GH68070 {
59+
60+
constexpr auto f = [x = 3]<typename Self>(this Self&& self) {
61+
return x;
62+
};
63+
64+
auto g = [x = 3]<typename Self>(this Self&& self) {
65+
return x;
66+
};
67+
68+
int test() {
69+
constexpr int a = f();
70+
static_assert(a == 3);
71+
return f() + g();
72+
}
73+
74+
}

0 commit comments

Comments
 (0)