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.
Under
-mm=rc, reassigning a parameter inside a loop whose condition isparam instanceof SomeClasscrashes the program with an access violation, in both JIT and AOT. gc and none print1.--emit=jit -mm=rc:Exception Code: 0xC0000005, top frames in JIT code--emit=exe -mm=rc: the exe segfaults-mm=gcand-mm=none: print1Found 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:
for (; x instanceof A; x = new B(1)) { ... }, with or without anything in the body usingx.let y = x; while (y instanceof A) { y = new B(1); }.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.