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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits