FA-90378 / Garbage collector invariants / Member archive
Reference counting: weak upgrade resurrects destroyed objects · case 03
upgrade() on an object whose last strong reference is gone succeeds and returns a destroyed object.
Case contract
Objects carry a strong count and a weak count. new id k: strong 1 (the creating reference), k null fields. drop id: release one strong reference. store src i dst: retain dst, then write, then release the old value. When the strong count reaches 0 the object is destroyed (recorded in freed, its fields released recursively in field order) and, if no weak references remain, its control block is deallocated too; unweak deallocates a destroyed object's block when the last weak reference goes. upgrade id succeeds (and adds a strong reference) only while the strong count is positive. Touching a deallocated block reports "use-after-free".
Why this case matters
Reference-counting collectors must order retains and releases and separate destruction from deallocation.
One recorded failure
Sample boundary fixtureThis sample comes from the broken implementation of a controlled reproducer.
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| upgrade after the last strong reference dies | {"dealloc": [], "freed": [31], "out": [true], "rc": {"31": [1, 0]}} | {"dealloc": [31], "freed": [31], "out": [false], "rc": {}} | Failed |
MEMBER ARCHIVE
The complete case is available to members.
This record includes three runnable implementations, regression fixtures, execution results, and source hashes.
Member access is invitation-based. Sign in with your invited account to inspect the sources.
Sign in to the archive ↗