blob: 4dd1294cef63b5a78c187354bdc1b18f2dbdae43 [file] [log] [blame]
// Copyright (c) 2019, 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.
f(Object x, bool b) {
if (x is num) {
if (/*num*/ x is int) {
try {
throw 'foo';
} catch (e) {
x = 1.5;
if (b) throw 'baz';
x = 0;
} finally {
// Note: on entry to the "finally", flow analysis
// conservatively de-promotes any variables that were assigned
// earlier in the statement, on the grounds that whatever type
// they are promoted to now, there's no guarantee that they
// had that type throughout execution of the try block. In
// this particular case that's over-conservative--we could in
// principle keep the promotion to "num", since the value
// assigned is compatible with "num"). But it doesn't seem
// worth the extra analysis cost to do so.
x;
}
}
}
}
f2(Object x, bool b) {
if (x is num) {
if (/*num*/ x is int) {
try {
throw 'foo';
} catch (e) {
/*int*/ x;
} finally {
// x has not been assigned to so the promotion is kept.
/*int*/ x;
}
}
}
}
f3(Object x, bool b) {
if (x is num) {
if (/*num*/ x is int) {
try {
throw 'foo';
} catch (e) {
/*int*/ x;
} finally {
// x has not been assigned to in the try/catch blocks so the promotion
// is kept here.
/*int*/ x;
x = 'foo';
}
}
}
}