https://github.com/Sirraide updated 
https://github.com/llvm/llvm-project/pull/154276

>From cd2b97cdd9d6cc3f575d71cee24c8f42f57bdb6a Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Tue, 19 Aug 2025 08:57:23 +0200
Subject: [PATCH 1/3] [Clang] [Sema] Always rebuild 'this' captured by value in
 a lambda with a dependent explicit object parameter

---
 clang/docs/ReleaseNotes.rst                   |  2 ++
 clang/lib/Sema/TreeTransform.h                |  7 ++++--
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp | 25 +++++++++++++++++++
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b86a9c437ffb1..7eccd6f4d2b92 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -234,6 +234,8 @@ Bug Fixes to C++ Support
   "intializing multiple members of union" coincide (#GH149985).
 - Fix a crash when using ``explicit(bool)`` in pre-C++11 language modes. 
(#GH152729)
 - Fix the parsing of variadic member functions when the ellipis immediately 
follows a default argument.(#GH153445)
+- Fixed a bug that caused ``this`` captured by value in a lambda with a 
dependent explicit object parameter to not be
+  instantiated properly. (#GH154054)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 055d3cd1a8609..485b1fa6f6875 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -14307,7 +14307,9 @@ 
TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
   // for type deduction, so we need to recompute it.
   //
   // Always recompute the type if we're in the body of a lambda, and
-  // 'this' is dependent on a lambda's explicit object parameter.
+  // 'this' is dependent on a lambda's explicit object parameter; we
+  // also need to always rebuild the expression in this case to clear
+  // the flag.
   QualType T = [&]() {
     auto &S = getSema();
     if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
@@ -14317,7 +14319,8 @@ 
TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
     return S.getCurrentThisType();
   }();
 
-  if (!getDerived().AlwaysRebuild() && T == E->getType()) {
+  if (!getDerived().AlwaysRebuild() && T == E->getType() &&
+      !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
     getSema().MarkThisReferenced(E);
diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp 
b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
index 8a78463d3a495..7325121582324 100644
--- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
@@ -264,3 +264,28 @@ void test() {
 // CHECK: call void @_ZNH5P27971C1cERKS0_
 // CHECK: call void @_ZN5P27971C1cEi
 }
+
+// This used to crash because we weren’t instantiating a dependent 'this'.
+namespace GH154054 {
+struct S {
+  int x;
+  auto byval() {
+    return [*this](this auto) { return this->x; };
+  }
+};
+
+void main() {
+  S s{ 42 };
+
+  if ( s.byval()() != 42)
+    __builtin_abort();
+}
+
+struct s {
+  auto f() { return [*this](this auto) { return this; }; }
+};
+
+void f() {
+  s().f()();
+}
+}

>From 87d52bf09ac44f40ad635c6c448efe24185f3d8e Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Tue, 19 Aug 2025 12:15:50 +0200
Subject: [PATCH 2/3] Add some check lines

---
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp 
b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
index 7325121582324..ba2f9c04e9a3d 100644
--- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
@@ -274,9 +274,11 @@ struct S {
   }
 };
 
+// CHECK-LABEL: define {{.*}} void @_ZN8GH1540544mainEv
 void main() {
   S s{ 42 };
 
+  // CHECK: call {{.*}} i32 @_ZZN8GH1540541S5byvalEvENHUlT_E_clIS2_EEDaS1_
   if ( s.byval()() != 42)
     __builtin_abort();
 }
@@ -285,7 +287,9 @@ struct s {
   auto f() { return [*this](this auto) { return this; }; }
 };
 
+// CHECK-LABEL: define {{.*}} void @_ZN8GH1540541fEv
 void f() {
+  // CHECK: call {{.*}} ptr @_ZZN8GH1540541s1fEvENHUlT_E_clIS2_EEDaS1_
   s().f()();
 }
 }

>From f1f4c938c21c017c1e821d07e79cb59c78072a88 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalm...@gmail.com>
Date: Tue, 19 Aug 2025 12:25:10 +0200
Subject: [PATCH 3/3] Add more check lines

---
 clang/test/CodeGenCXX/cxx2b-deducing-this.cpp | 27 +++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp 
b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
index ba2f9c04e9a3d..9664a866376ae 100644
--- a/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/CodeGenCXX/cxx2b-deducing-this.cpp
@@ -283,13 +283,36 @@ void main() {
     __builtin_abort();
 }
 
+// CHECK-LABEL: define {{.*}} i32 
@_ZZN8GH1540541S5byvalEvENHUlT_E_clIS2_EEDaS1_(i32 %.coerce)
+// CHECK: entry:
+// CHECK:   %0 = alloca %class.anon.11, align 4
+// CHECK:   %coerce.dive = getelementptr inbounds nuw %class.anon.11, ptr %0, 
i32 0, i32 0
+// CHECK:   %coerce.dive1 = getelementptr inbounds nuw %"struct.GH154054::S", 
ptr %coerce.dive, i32 0, i32 0
+// CHECK:   store i32 %.coerce, ptr %coerce.dive1, align 4
+// CHECK:   %1 = getelementptr inbounds nuw %class.anon.11, ptr %0, i32 0, i32 0
+// CHECK:   %x = getelementptr inbounds nuw %"struct.GH154054::S", ptr %1, i32 
0, i32 0
+// CHECK:   %2 = load i32, ptr %x, align 4
+// CHECK:   ret i32 %2
+
 struct s {
-  auto f() { return [*this](this auto) { return this; }; }
+  int q;
+  auto f() {
+    return [*this](this auto) { return this; };
+  }
 };
 
 // CHECK-LABEL: define {{.*}} void @_ZN8GH1540541fEv
 void f() {
   // CHECK: call {{.*}} ptr @_ZZN8GH1540541s1fEvENHUlT_E_clIS2_EEDaS1_
-  s().f()();
+  s{}.f()();
 }
+
+// CHECK-LABEL: define {{.*}} ptr 
@_ZZN8GH1540541s1fEvENHUlT_E_clIS2_EEDaS1_(i32 %.coerce)
+// CHECK: entry:
+// CHECK:   %0 = alloca %class.anon.12, align 4
+// CHECK:   %coerce.dive = getelementptr inbounds nuw %class.anon.12, ptr %0, 
i32 0, i32 0
+// CHECK:   %coerce.dive1 = getelementptr inbounds nuw %"struct.GH154054::s", 
ptr %coerce.dive, i32 0, i32 0
+// CHECK:   store i32 %.coerce, ptr %coerce.dive1, align 4
+// CHECK:   %1 = getelementptr inbounds nuw %class.anon.12, ptr %0, i32 0, i32 0
+// CHECK:   ret ptr %1
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to