blob: d2fa1f2a3c6d78b3e38b3820d85a49595f4f2a6c [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
// Regression test for dart2js that used to generate wrong code for
// it. The bug happened in the SSA type propagation.
class A {
next() => new B();
doIt() => null;
bool get isEmpty => false;
foo() => 42;
bar() => 54;
}
bool entered = false;
class B extends A {
foo() => 54;
doIt() => new A();
bool get isEmpty => true;
bar() => entered = true;
}
// (1) At initialization phase of the type propagation, [a] would be
// marked as [exact A].
// (2) Will make the loop phi [b] typed [null, exact A].
// (3) Will create a [HTypeKnown] [exact A] for [b].
// (4) Will create a [HTypeKnown] [exact A] for [b] and update users
// of [b] to use this [HTypeKnown] instead.
// (5) [a] will be updated to [subclass A].
// (6) Will change the [HTypeKnown] of [b] from [exact A] to [subclass A].
// (7) Receiver is [subclass A] and it will refine it to
// [subclass A]. We used to wrongly assume there was
// no need to update the [HTypeKnown] created in (3).
// (8) Consider that bar is called on an [exact A] (the [HTypeKnown]
// created in (3)) and remove the call because it does not have
// any side effects.
main() {
var a = new A();
for (var i in [42]) {
a = a.next();
}
// (1, 5)
var b = a;
while (b.isEmpty) {
// (4, 6)
b.foo(); // (3, 7)
b.bar(); // (8)
b = b.doIt(); // (2)
}
if (!entered) throw 'Test failed';
}