[clang] [Clang][CodeGen] Track EH cleanup depth for guarded init and pop correctly (PR #199508)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 05:48:17 PDT 2026
mkovacevic99 wrote:
Just to be clear about what my patch does — it does not change the capture lifetime rule. Captures are still destroyed at the end of the enclosing scope, exactly as they are on trunk. The patch only makes that end-of-scope cleanup conditional and gives it a dominating address, so it's emitted correctly when the initializer runs under the guard branch. On current trunk (without this patch) that path is broken: it either ICEs, or — when there's a throwing call after the init — runs __cxa_guard_abort on a guard that was already initialized.
@ahatanak — I compiled your example. The captured copy of a is destroyed at the end of test(), after bl(), and it's guarded so it only runs on the call that actually performed the initialization. So it stays correct and works on every call — the patch preserves that behavior rather than breaking it.
@rjmccall — agreed on the "simple lifetime extension, don't destroy the captures while the block may still be in use" framing; the patch keeps that. The captures are still destroyed at end of scope, never earlier.
On the heap-based point: agreed that storing a block pointer into a static (static BlockTy b = ^{...}; b();) needs the block to be heap-based to be valid across calls. My patch makes the single-activation case correct but doesn't heap-promote the block, which feels orthogonal to this crash fix. Do you want the heap-promotion handled in this PR, or as a follow-up?
[guarded-init-block-capture.patch](https://github.com/user-attachments/files/29292901/guarded-init-block-capture.patch)
https://github.com/llvm/llvm-project/pull/199508
More information about the cfe-commits
mailing list