Repository navigation
rc: hold an argument whose place the call overwrites - #653
Merged
Merged
Conversation
An argument is borrowed, and two shapes overwrote the place it was read from while the call still used it: - a later argument of the same call assigns it: `f(n, (n = mk(), n))` for a local, a parameter or a local's field (A1). #647 covered a global; a local was still freed before the call ran. - the callee is given the object as well: `f(n, n.items[0])`, where `f` overwrites `p.items[0]` and then reads its other parameter (R8). Under rc holdGlobalArguments now also holds an argument read out of a slot or a place that something between the read and the call overwrites, and an argument read out of a field or an element of a value given as another argument of the call: retained where it is read, released after the call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`f({ v: n.v }, (n = mk(), 0))` and `f(n.items[0], (n = mk(), 0))`: the
argument is read out of a field or an element of `n`, and the later
argument's assignment to `n` gives back the object it was read out of.
overwrittenBeforeCall looked only at the argument's own place; it now
walks out through the fields and elements it was read through, and
holds the argument when any of those values' places is overwritten
before the call. Found by the fuzzer (#646) past the first 1000
programs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-overwritten # Conflicts: # tslang/lib/TypeScript/OwnedReturnConsumptionPass.cpp # tslang/test/tester/CMakeLists.txt
ASDAlexander77
added a commit
that referenced
this pull request
Oct 23, 2026
#653 added a same-block check for an argument whose slot or place a later argument overwrites (overwrittenBeforeCall); it runs before localAssignedBefore, which still covers a conditional argument, a closure assigning a captured local, a field of a folded const, and a handle under own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ASDAlexander77
added a commit
that referenced
this pull request
Oct 23, 2026
…nt-slot-assigned Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 23, 2026
ASDAlexander77
added a commit
that referenced
this pull request
Oct 23, 2026
…other name (#663) `f7((p12.n = mk(7), p12.n), (HG.n = mk(9), p13))` with `p12` being `HG`: the first argument is read out of `p12.n`, and the second argument's `HG.n = mk(9)` gives back the block it read. The caller holds an argument whose place is overwritten between the read and the call (#653), but samePlace compared places by name. A store to one field of another object of the same class, or to an element of another array of the same type, may be the same place, and now holds the argument as well. Fuzzer (#646), 80037. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes fuzzer bugs A1 (local, parameter and local-field forms) and R8 (#646) under rc.
Why
Arguments are borrowed. In both shapes the place an argument was read from is overwritten while the call still uses it:
Fix (rc only)
holdGlobalArgumentsnow also holds:ts.Storeorts.ReleaseSlotto the same place; a new helpersamePlacecompares one variable, one global, or one field of one value);The overwrite check walks out through the fields and elements the argument was read through (follow-up commit 10b6e91). So
f({ v: n.v }, (n = mk(), 0))andf(n.items[0], (n = mk(), 0))are held as well: there the later argument gives back the object the argument was read out of. The fuzzer found these past its first 1000 programs, andlocalsFieldInLiteralandlocalsElementin the test cover them.As with the global hold (#647/#648), it is retained where it is read and released after the call.
Tests
tests/00argument_place_overwritten.tscovers:On Linux main, the local, field and R8 cases each fail on their own. The parameter case already passes on main and is kept as coverage. The test runs compiled, under JIT, and in the rc/none corpus.
Verification
ctest -C Release: Windows 4982/4982, WSL Linux 4964/4964.mm_fuzz.py run --count 500 --seed 1and--count 1000 --seed 2: no rc failures. Seed 2 had 5 rc A1 failures before this change. Only the known own failures remain (R1, O4, A1 own).🤖 Generated with Claude Code