[clang] [Clang] Fix constant evaluating a captured variable in a lambda (PR #68090)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 3 05:18:15 PDT 2023
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/68090
>From d3c5351c0bddd0bf9cd743471beafbf18bbab77c Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 3 Oct 2023 13:19:50 +0200
Subject: [PATCH 1/2] [Clang] Fix constant evaluating a captured variable in a
lambda
with an explicit parameter.
Fixes #68070
---
clang/lib/AST/ExprConstant.cpp | 8 +++++++-
.../SemaCXX/cxx2b-deducing-this-constexpr.cpp | 18 ++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a142ea7c47a4730..e8bf037c879c640 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8366,8 +8366,14 @@ 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);
// Start with 'Result' referring to the complete closure object...
- Result = *Info.CurrentCall->This;
+ 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/SemaCXX/cxx2b-deducing-this-constexpr.cpp b/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
index 44de0d711674ba8..9dbea17dd2cae34 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp
@@ -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();
+}
+
+}
>From 535fda1ccf5804f2c350b58ced8ee5e98c6583bd Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Tue, 3 Oct 2023 14:17:54 +0200
Subject: [PATCH 2/2] Address Timm's feedback
---
clang/lib/AST/ExprConstant.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index e8bf037c879c640..d77597d063eb2a8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8366,9 +8366,9 @@ 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);
// Start with 'Result' referring to the complete closure object...
- if (MD->isExplicitObjectMemberFunction()) {
+ 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);
More information about the cfe-commits
mailing list