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
