Skip to content

rc: a const bound method with a declared type holds its object - #662

Merged
ASDAlexander77 merged 3 commits into
mainfrom
fix-rc-const-bound-method-cast
Oct 23, 2026
Merged

ASDAlexander77 merged 3 commits into
mainfrom
fix-rc-const-bound-method-cast

Conversation

@ASDAlexander77

@ASDAlexander77 ASDAlexander77 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes fuzzer repro 80194 (#646), found in a fresh range (80001). It fails on main.

const c15: () => number = G.items[0].get;
G = mk(4);           // frees the old G, its items, and the V c15 is bound to
print(c15());        // 4.94066e-324, then the assert fails

Why

Under rc, a const made over a read of a field, an element, a global or a local holds a count of its own (processConstRef, needsIdentityStorage). That includes an interface or a bound method made over such a read, which #644 covered. viewedValue finds the value a bound method is made over, but it didn't look through casts. A declared type (const c: () => number = ...) casts the bound method to a hybrid function, so no read was seen. The const was then folded, with no count.

Fix

viewedValue strips casts before it looks for the interface or the bound method. Its callers already handle what it returns.

Tests

tests/00const_bound_method_declared_type.ts has a declared-type bound method over each of:

  • an element of a global (the fuzzer's shape)
  • a field of a global
  • a field of a local
  • a local
  • a global reassigned in a loop

Each case fails on its own under rc on Linux without the fix. The object's x is its first field, so the bytes glibc writes into a freed block overwrite it. The test runs compiled, under JIT, and in the rc/none corpus.

Verification

🤖 Generated with Claude Code

ASDAlexander77 and others added 3 commits October 23, 2026 10:34
`const c: () => number = G.items[0].get`: the declared type casts the
bound method to a hybrid function, and viewedValue did not look
through that cast, so processConstRef saw no bound method over a read
of a field, an element, a global or a local. The const was folded with
no count, and `G = mk()` freed the object `c()` still ran on.
viewedValue now strips casts first. Fuzzer (#646), 80194.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit a55fd48 into main Oct 23, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-rc-const-bound-method-cast branch October 23, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant