Author: Akira Hatanaka
Date: 2026-09-02T08:28:03-07:00
New Revision: b5401fb149dc12ba8b1c5bb088416d9244631da7

URL: 
https://github.com/llvm/llvm-project/commit/b5401fb149dc12ba8b1c5bb088416d9244631da7
DIFF: 
https://github.com/llvm/llvm-project/commit/b5401fb149dc12ba8b1c5bb088416d9244631da7.diff

LOG: Remove overly strict assertion for this-capture in blocks (#219080)

TransformBlockExpr asserted that if the instantiated block captures
'this', the uninstantiated pattern block must also have captured it.
This assumption doesn't always hold: a block that accesses a member
through a dependent qualified-id (e.g., 'T::m' inside a template
deriving from T) has no way to know at parse time that the access will
resolve to an implicit 'this->m', since T is unknown. Once the template
is instantiated and 'T::m' resolves to a non-static data member, the
instantiated block legitimately captures 'this' even though the pattern
never did.

rdar://184776458

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/Sema/TreeTransform.h
    clang/test/CodeGenObjCXX/block-in-template-inst.mm

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index db9220d43936a..bf295981710ac 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -636,6 +636,8 @@ features cannot lower the translation-unit ABI level;
   threshold to the target's `size_t` width instead of using a fixed
   threshold of `1 << 60` regardless of the target.
 - Fixed a crash when generating fake uses for parameters of bodyless 
destructors with `-fextend-variable-liveness`.
+- Fixed an assertion failure when instantiating a block that captures
+  `this` via a member access through a dependent base class.
 
 ### OpenACC Specific Changes
 

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index f1a3493ce9ea3..5f9a7d53fb259 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -17941,12 +17941,6 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr 
*E) {
                                                  oldCapture));
       assert(blockScope->CaptureMap.count(newCapture));
     }
-
-    // The this pointer may not be captured by the instantiated block, even 
when
-    // it's captured by the original block, if the expression causing the
-    // capture is in the discarded branch of a constexpr if statement.
-    assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
-           "this pointer isn't captured in the old block");
   }
 #endif
 

diff  --git a/clang/test/CodeGenObjCXX/block-in-template-inst.mm 
b/clang/test/CodeGenObjCXX/block-in-template-inst.mm
index 1ecd820be4501..50fc0896fd76d 100644
--- a/clang/test/CodeGenObjCXX/block-in-template-inst.mm
+++ b/clang/test/CodeGenObjCXX/block-in-template-inst.mm
@@ -68,3 +68,14 @@ void curry() {
     auto t = c(1)(10)(100);
   }
 }
+
+namespace ThisCaptureViaDependentBase {
+  // This used to crash.
+  struct Base { int m; };
+
+  template <typename T> struct S : T {
+    void f() { ^{ (void)T::m; }(); }
+  };
+
+  template struct S<Base>;
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to