Skip to content

Commit d3c5351

Browse files
committed
[Clang] Fix constant evaluating a captured variable in a lambda
with an explicit parameter. Fixes llvm#68070
1 parent 55d8f0c commit d3c5351

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8366,8 +8366,14 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
83668366
return false;
83678367

83688368
if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
8369+
auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
83698370
// Start with 'Result' referring to the complete closure object...
8370-
Result = *Info.CurrentCall->This;
8371+
if (MD->isExplicitObjectMemberFunction()) {
8372+
APValue *RefValue =
8373+
Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0));
8374+
Result.setFrom(Info.Ctx, *RefValue);
8375+
} else
8376+
Result = *Info.CurrentCall->This;
83718377
// ... then update it to refer to the field of the closure object
83728378
// that represents the capture.
83738379
if (!HandleLValueMember(Info, E, Result, FD))

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

Lines changed: 18 additions & 0 deletions
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)