Class RetainReleaseBalanceVerifier
Once main is on the +1 convention it has no native backend and no runtime leak gate, so
nothing else structurally checks that a RETAIN was dropped correctly during IR generation.
The JVM backend treats RETAIN/RELEASE as no-ops and SCOPE_* as debug-only, so
a mis-balanced scope compiles and runs fine on the JVM yet is a native leak or use-after-free. This
verifier makes the +1 invariant STRUCTURAL and backend-independent: it runs at compile time on every
construct (not just corpus runtime paths), so "if it compiles, it's good" extends to ARC balance.
Invariant checked (report-only for now — see IRAnalysis): within a single method body,
a scope that is SCOPE_EXIT'd or SCOPE_REGISTER'd into must first be SCOPE_ENTER'd,
and a scope that is entered must be exited on at least one path. These are branch-independent: an orphan
exit is a double-release and an enter with no exit anywhere is an outright leak. Deliberately NOT flagged
is SCOPE_ENTER count != SCOPE_EXIT count — a method with multiple return paths correctly emits one
SCOPE_EXIT per path for a single SCOPE_ENTER (e.g. _isSet enters once and exits on
both the return-false and return-true branches), so counts diverge legitimately and only one exit runs on
any path. Detecting the true per-path leak (a scope not exited on SOME path) needs control-flow-graph path
analysis and is the prerequisite for promoting this phase to enforcing.
The retain heuristic (a RETAIN of a non-return, non-field temp with no matching
SCOPE_REGISTER) is reported as informational only — it flags likely leaks but has known
false-positive shapes (escaping results, argument ownership transfer) that the report-only corpus run
is meant to characterise before any promotion to enforcing.
Collection recurses into the two nested-block carriers (ControlFlowChainInstr guard/condition/
body/default/try/finally lists and ForRangePolymorphicInstr init/body/dispatch lists) so a
scope entered in one nested list and exited in another still balances. The return variable is always
rtn (ownership transferred to the caller) and field paths contain '.' (store-site
release/retain pair) — both are excluded from the retain heuristic.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static final recordA single balance finding for one construct/operation. -
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) List<RetainReleaseBalanceVerifier.Finding> verify(IRConstruct construct) Verify every operation body in the construct and return all findings (empty when balanced).
-
Field Details
-
RETURN_VARIABLE
- See Also:
-
-
Constructor Details
-
RetainReleaseBalanceVerifier
RetainReleaseBalanceVerifier()
-
-
Method Details
-
verify
Verify every operation body in the construct and return all findings (empty when balanced).
-