[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 04:23:00 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

<details>
<summary>Changes</summary>

with an explicit parameter.

Fixes #<!-- -->68070

---
Full diff: https://github.com/llvm/llvm-project/pull/68090.diff


2 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+7-1) 
- (modified) clang/test/SemaCXX/cxx2b-deducing-this-constexpr.cpp (+18) 


``````````diff
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();
+}
+
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/68090


More information about the cfe-commits mailing list