Skip to content

-mm=rc: reassigning a parameter in a loop conditioned on its instanceof crashes #512

Description

@ASDAlexander77

Under -mm=rc, reassigning a parameter inside a loop whose condition is param instanceof SomeClass crashes the program with an access violation, in both JIT and AOT. gc and none print 1.

class A { constructor(public a: number) {} }
class B { constructor(public b: number) {} }

function f(x: A | B) {
    let n = 0;
    while (x instanceof A) {
        x = new B(1);
        n++;
    }

    return n;
}

function main() {
    print(f(new A(5)));
}
  • --emit=jit -mm=rc: Exception Code: 0xC0000005, top frames in JIT code
  • --emit=exe -mm=rc: the exe segfaults
  • -mm=gc and -mm=none: print 1

Found on main 61d3092. It also crashes on a build from before #510, so it is not caused by the recent loop changes.

What it needs:

  • The same crash with for (; x instanceof A; x = new B(1)) { ... }, with or without anything in the body using x.
  • Copying the parameter into a local first works: let y = x; while (y instanceof A) { y = new B(1); }.
  • Reassigning the parameter in a plain counting loop works: for (let i = 0; i < 1; i++) { x = new B(1); }.
  • if (x instanceof A) { ... } x = new B(1); works.

So it seems to need all three: a parameter, written inside the loop, in a loop whose condition tests it with instanceof. A likely place to look is how rc retains/releases a parameter slot that the loop condition reads on each iteration.

00for_condition_narrowing.ts (in the for-narrowing PR) loops over a local copy because of this. Its comment refers to the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions