diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t01.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t01.dart new file mode 100644 index 0000000000..a52a62f8ee --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t01.dart @@ -0,0 +1,75 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in `Si` then it is +/// "possibly assigned" in `F`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +Never foo() => throw "Never"; + +test1() { + late int i; + try { + } catch (_) { + foo(); + i = 42; + } finally { + i; // Possibly assigned // TODO (sgrekhov) https://github.com/dart-lang/co19/pull/3145/files#r2044357821 + } +} + +test2(Never n) { + late int i; + try { + } catch (_) { + n; + (i,) = (42,); + } finally { + i; + } +} + +test3(T n) { + late int i; + try { + } catch (_) { + n; + (x: i) = (x: 42); + } finally { + i; + } +} + +test4() { + late int i; + try { + } catch (_) { + foo(); + C(v: i) = C(42); + } finally { + i; + } +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t02.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t02.dart new file mode 100644 index 0000000000..808f7b19f9 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t02.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in `Si` then it is +/// "possibly assigned" in `F`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1() { + late int i; + try { + } catch (_) { + if (false) { + i = 42; + } + } finally { + i; // Possibly assigned + } +} + +test2() { + late int i; + try { + } catch (_) { + if (false) { + (i, ) = (42, ); + } + } finally { + i; + } +} + +test3() { + late int i; + try { + } catch (_) { + if (false) { + (x: i) = (x: 42); + } + } finally { + i; + } +} + +test4() { + late int i; + try { + } catch (_) { + if (false) { + C(v: i) = C(42); + } + } finally { + i; + } +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t03.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t03.dart new file mode 100644 index 0000000000..d139f2d2bf --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t03.dart @@ -0,0 +1,81 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in `Si` then it is +/// "possibly assigned" in `F`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1() { + int i; + try { + } catch (_) { + i = 42; + } finally { + i; // Possibly assigned +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test2() { + int i; + try { + } catch (_) { + (i,) = (42,); + } finally { + i; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test3() { + int i; + try { + } catch (_) { + (x: i) = (x: 42); + } finally { + i; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test4() { + int i; + try { + } catch (_) { + C(v: i) = C(42); + } finally { + i; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t04.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t04.dart new file mode 100644 index 0000000000..e7341afe68 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A01_t04.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some promoted variable is captured in `Si` then +/// it is demoted in `F`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1(int? n) { + if (n != null) { // `n` promoted to `int` + try { + print("To avoid empty body"); + } catch (_) { + () {n = 42;}; // `n` demoted to `int?` + } finally { + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } + } +} + +test2(int? n) { + if (n != null) { + try { + } catch (_) { + () {(n,) = (42,);}; + } finally { + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } + } +} + +test3(int? n) { + if (n != null) { + try { + } catch (_) { + () {(x: n) = (x: 42);}; + } finally { + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } + } +} + +test4(int? n) { + if (n != null) { + try { + } catch (_) { + () {C(v: n) = C(42);}; + } finally { + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } + } +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t01.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t01.dart new file mode 100644 index 0000000000..47805f2415 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t01.dart @@ -0,0 +1,88 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in `Si` and it throws +/// then it is definitely unassigned in dead code `after(N)`. +/// @author sgrekhov22@gmail.com +/// @issue 60503 + +class C { + int v; + C(this.v); +} + +Never foo() => throw "Never"; + +test1() { + late int i; + try { + } catch (_) { + foo(); + i = 42; + } finally { + } + i; // Definitely unassigned and in dead code +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test2(Never n) { + late int i; + try { + } catch (_) { + (i,) = (42,); + n; + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test3(T n) { + int i; + try { + } catch (_) { + n; + (x: i) = (x: 42); + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test4() { + int i; + try { + } catch (_) { + C(v: i) = C(42); + foo(); + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t02.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t02.dart new file mode 100644 index 0000000000..45fd9e2b70 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t02.dart @@ -0,0 +1,89 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in dead code in `Si` +/// then it is definitely unassigned `after(N)`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1() { + late int i; + try { + } catch (_) { + if (false) { + i = 42; + } + } finally { + } + i; // Definitely unassigned +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test2() { + late int i; + try { + } catch (_) { + if (false) { + (i,) = (42,); + } + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test3() { + late int i; + try { + } catch (_) { + if (false) { + (x: i) = (x: 42); + } + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test4() { + late int i; + try { + } catch (_) { + if (false) { + C(v: i) = C(42); + } + } finally { + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t03.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t03.dart new file mode 100644 index 0000000000..c2a0223819 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t03.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some variable is assigned in `Si` then it is +/// "possibly assigned" `after(N)`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1() { + late int i; + try { + } catch (_) { + i = 42; + } finally { + } + i; +} + +test2() { + late int i; + try { + } catch (_) { + (i,) = (42,); + } finally { + } + i; +} + +test3() { + late int i; + try { + } catch (_) { + (x: i) = (x: 42); + } finally { + } + i; +} + +test4() { + late int i; + try { + } catch (_) { + C(v: i) = C(42); + } finally { + } + i; +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t04.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t04.dart new file mode 100644 index 0000000000..bbaaea54bc --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A02_t04.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2025, 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. + +/// @assertion try catch finally: If `N` is a try/catch/finally statement of the +/// form `try B1 alternatives finally F` then: +/// - Let `before(B1) = before(N)` +/// - Let `before(Si) = join(after(B1), conservativeJoin(before(N), +/// assignedIn(B1), capturedIn(B1)))`, where `Si` +/// is the body of the i'th alternative +/// - Let +/// `after(N) = join(attachFinally(after(B1), before(F), after(F)), M1 .. Mk)` +/// where `Mj = attachFinally(after(Sj), before(F), after(F))` +/// +/// @description Checks that if some promoted variable is captured in `Si` then +/// it is demoted `after(N)`. +/// @author sgrekhov22@gmail.com + +class C { + int v; + C(this.v); +} + +test1(int? n) { + if (n != null) { // `n` promoted to `int` + try { + } catch (_) { + () {n = 42;}; // `n` demoted to `int?` + } finally { + } + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test2(int? n) { + if (n != null) { + try { + } catch (_) { + () {(n,) = (42,);}; + } finally { + } + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test3(int? n) { + if (n != null) { + try { + } catch (_) { + () {(x: n) = (x: 42);}; + } finally { + } + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test4(int? n) { + if (n != null) { + try { + } catch (_) { + () {C(v: n) = C(42);}; + } finally { + } + n.isEven; +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +main() { + print(test1); + print(test2); + print(test3); + print(test4); +} diff --git a/TypeSystem/flow-analysis/reachability_try_finally_A02_t04.dart b/TypeSystem/flow-analysis/reachability_try_finally_A02_t04.dart index bea7e760a6..57f7802a57 100644 --- a/TypeSystem/flow-analysis/reachability_try_finally_A02_t04.dart +++ b/TypeSystem/flow-analysis/reachability_try_finally_A02_t04.dart @@ -35,7 +35,7 @@ test1(int? n) { test2(int? n) { if (n != null) { try { - () {(n,) = (42,);}; + () {(n,) = (42,);}; } finally { n.isEven; // ^^^^^^