Skip to content

rc: a const read through an interface field or a handle's value holds a count - #651

Open
ASDAlexander77 wants to merge 1 commit into
mainfrom
fix-rc-const-interface-shared-read
Open

ASDAlexander77 wants to merge 1 commit into
mainfrom
fix-rc-const-interface-shared-read

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Fixes fuzzer bugs R2 and R7 (#646): a const read through an interface field, or out of a Shared<T> handle, dangled once that field got a new value.

const v = ix.v;      ix.v = mv(1);      v.w = ...;   // R7: SIGABRT
const v = GS.value;  GS.value = mv(1);  v.a[0];      // R2: SIGSEGV

Why

A const read out of a place is folded into the read itself, so it holds no count of its own. #635 gave a const read out of a class field storage under rc (readsField, through ts.PropertyRef). A read through an interface goes through ts.InterfaceSymbolRef, and a read of a handle's value goes through ts.SharedValueRef, so neither matched.

Fix (rc only)

readsField now recognises those two refs as well. Such a const gets storage like a let, as the class field, element and global cases already do (#635, #641, #642, #644, #647). Under own the folded read stays a borrow, and own rejects it when the place is overwritten.

Tests

tests/00const_interface_field_read.ts covers:

  • an interface over an object literal and over a class
  • an interface in a loop
  • a handle's value overwritten
  • the handle itself replaced

Each case fails under rc on its own without the fix (Linux). The test runs compiled, under JIT, and in the rc/none corpus.

Verification

  • ctest -C Release: Windows 4982/4982, WSL Linux 4964/4964.
  • Replaying the fuzzer's repros on Linux: R2-shared-value, R2-shared-value-assign and R7-iface-field-const now match gc.
  • mm_fuzz.py --jobs 10 run --count 500 --seed 1: only the 3 known own failures (R1, O4).

🤖 Generated with Claude Code

… a count

`const v = ix.v; ix.v = mv();` and `const v = GS.value; GS.value = mv();`
freed what `v` still read: the const was folded into the read, which
holds no count. #635 gave a const read out of a class field storage
under rc; a read through an interface (ts.InterfaceSymbolRef) or out of
a Shared<T> handle (ts.SharedValueRef) is a field read as well, and now
gets the same. Under own the folded read stays a borrow, rejected when
the place is overwritten. Fuzzer (#646) R2 and R7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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