Files
Adam Cmiel 01d4de807e [ExistentialSpecializer] Fix missing destroy_addr for class-constrained @in_guaranteed existential
When the ExistentialSpecializer transforms a function with a
class-constrained existential argument that is passed as an address
(@in_guaranteed) and not consumed by the callee, both the specialized
function cloner and the thunk body generator emit:

  load [copy] -> open_existential_ref/init_existential_ref ->
  alloc_stack -> store [init] -> apply @in_guaranteed -> dealloc_stack

The load [copy] creates a +1 that is forwarded into the alloc_stack.
Since the callee borrows (@in_guaranteed) but does not consume, the
value remains initialized after the apply. The dealloc_stack without a
preceding destroy_addr leaks the +1 and triggers the
MemoryLifetimeVerifier: 'memory is initialized, but shouldn't be'.

Fix: in both the cloner (cloneArguments, Class + address case) and the
thunk (populateThunkBody, Class + address + non-consumed case), add
the alloc_stack to CleanupValues / set DestroyValue so that
destroy_addr is emitted before dealloc_stack when the argument is not
consumed. This matches the existing handling for the Opaque
representation case.
2026-06-23 13:51:16 -04:00
..