Skip to content

-mm=rc: const b = a (a let of a class) takes no reference; reassigning a frees what b holds #454

Closed

Description

@ASDAlexander77

Under -mm=rc, const b = a, where a is a let holding a class instance, does not keep the instance alive. Reassigning a frees the object while b still refers to it.

class Node { v = 0; name = ""; }

function main() {
    let a = new Node();
    a.name = "first" + 1;
    const b = a;
    a = new Node();
    let keep: string[] = [];
    for (let i = 0; i < 1000; i++) keep.push("k" + i);
    assert(b.name == "first1", "b still holds the first node");
    print("done.");
}

tslang --emit=jit --no-default-lib, main 8b9d631:

  • gc and none: done.
  • rc: assertion failed: b still holds the first node, exit code 3. The first Node and its string are freed when a is reassigned, and the keep loop reuses the memory.

The same program with only a number field (v) passes under rc, because the freed block is not reused before b.v is read. The bug is still there, it just does not show.

Probable cause: a const initialised from a let is folded into a read of the let rather than given storage and a reference of its own. Branch own-shared (own phase 8) fixed this for Shared<T> handles only, by giving a const of that type identity storage (needsIdentityStorage, beside ArrayType). Class instances still need the fix.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions