You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
lifter: destroy an inheritable object through its vtable, even an emp… (#2532)
…ty one
A closure's environment is a ref to a compiler-made object deriving from
RootObj, and the closure value knows it only as `(ref RootObj)`. Its
=destroy decremented the count and freed the block, but never ran the
env's OWN destructor: RootObj has no fields, `isTrivialTypeDecl` called
it trivial, and `emitRefDestructor` skipped the payload. Every captured
string, ref or resource in every closure leaked.
An object with RTTI is never trivial for `=destroy` now: the value may
be a DERIVED object that owns something, and its `=destroy` is a method.
The synthesized `=destroy_RootObj` is an empty method — the vtable slot
is the point — and the `ref RootObj` hook dispatches through it to the
env's synthesized destroy, which releases the captures. Same mechanism
the existing user-hierarchy dispatch (txdestroy) relies on; `=wasMoved`
already had this exception for the vtable field.
Test: tclosure_env_release — a captured resource with a loud destructor
is released when the last reference to the closure goes, and not before.
Co-authored-by: Ryan Walklin <ryan@kaitakeradiology.co.nz>
0 commit comments