Skip to content

Commit 67aa87d

Browse files
committed
Record the elision review verdicts and Bug 14
Both reviews passed: the soundness review proved residual balance per consumer kind against the pre-elision build, and the adversarial review reproduced no double-free, use-after-free, or elision-introduced leak across about 29 attack programs with a finalizer oracle. Record the verdicts and the two plausible-only approximation gaps (control_flow_between not treating Return or Call as control flow, safe today, to be made explicit by the dominance refinement) in RC_ELISION.md. Record Bug 14, found pre-existing by the adversarial review: continue inside a while skips the drops of references created earlier in the loop body, leaking them on the continued path. The fix direction mirrors the early-return drop handling.
1 parent 0bcd2fd commit 67aa87d

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

plans/KNOWN_BUGS.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ declared without a return-type annotation (its inferred return is indeterminate)
7171
loose typing the dedicated paths had, narrowed here rather than fully closed. Found by the arc 1a
7272
adversarial review, reconfirmed as the residual channel by the arc 1b and Bug 12 reviews.
7373

74+
## Bug 14 (OPEN, moderate): `continue` skips drops of references created earlier in the loop body
75+
76+
A `continue` inside a `while` jumps to the next iteration without releasing reference-typed values
77+
created earlier in that iteration's body, so each continued iteration leaks them (a finalizer-bearing
78+
resource created before the `continue` never runs its finalizer on the continued path). The normal
79+
fall-through end of the body drops them correctly, so this is drop placement on the `continue` jump
80+
path, the same family as the early-return drops that `emit_return_param_drops` handles for `return`.
81+
Pre-existing, found by the reference-count elision adversarial review by differential comparison
82+
against the pre-elision build (both leak identically, so the elision is unrelated). Fix direction:
83+
emit the current iteration's scope-end drops before the `continue` jump, mirroring the return path.
84+
7485
## Bug 13 (FIXED): a block match-arm in value position yielded the wrong value
7586

7687
Three distinct issues surfaced together while prototyping a lisp interpreter. Their status differs:

plans/RC_ELISION.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,24 @@ references), and a single drop the move dominates (approximated as no control fl
2222
drop). The `Drop` instruction itself stays in the IR, only its DecRef emission is skipped, so register
2323
lifetime bookkeeping is untouched.
2424

25-
Measured on the http hello path: incref 102 to 81 and decref 172 to 151 per request. A soundness
26-
review traced the refcount balance per consumer kind against the pre-elision build (the residual
27-
`allocations + incref - decref` must match exactly) and found no imbalance anywhere, including the
28-
callee-returns-its-param and direct-finalizer cases. The invariant is caller-side pair cancellation:
29-
a matched retain and drop with the variable provably dead between them cancel regardless of what the
30-
consumer does.
25+
Measured on the http hello path: incref 102 to 81 and decref 172 to 151 per request. Two independent
26+
reviews confirmed soundness. The soundness review traced the refcount balance per consumer kind
27+
against the pre-elision build (the residual `allocations + incref - decref` must match exactly) and
28+
found no imbalance anywhere, including the callee-returns-its-param and direct-finalizer cases. The
29+
invariant is caller-side pair cancellation: a matched retain and drop with the variable provably dead
30+
between them cancel regardless of what the consumer does. The adversarial review ran about 29 attack
31+
programs (conditional moves, reassignment, spawn, loops with continue, match payloads, generics, a
32+
200-iteration stress with a printing finalizer as the oracle) differentially against the pre-elision
33+
build and reproduced no double-free, use-after-free, or elision-introduced leak. It also confirmed
34+
why the guards hold: single-drop plus no-control-flow-between put the move and its drop in one basic
35+
block, so the move trivially dominates the drop.
36+
37+
Two review by-products are recorded elsewhere or below: a pre-existing `continue` drop-placement leak
38+
(KNOWN_BUGS Bug 14, identical on the pre-elision build), and two plausible-only approximation gaps.
39+
`control_flow_between` does not treat `Return` or `Call` as control flow. A `Return` between a move
40+
and the drop makes that drop dead code, and a `Call` returns to the next instruction, so neither was
41+
turnable into a fault, but the dominance-based refinement should make both explicit rather than
42+
incidental.
3143

3244
## The next lever: borrow elision (PLANNED)
3345

0 commit comments

Comments
 (0)