From 700668cf46947a0d82d45e6c329beb79531c05fe Mon Sep 17 00:00:00 2001 From: sgrekhov Date: Wed, 16 Apr 2025 14:11:57 +0300 Subject: [PATCH] #3057. Add more promotion tests --- .../reachability_try_catch_A03_t02.dart | 49 ++++++++++++ .../reachability_try_catch_A04_t03.dart | 36 +++++++++ ...eachability_try_catch_finally_A03_t02.dart | 76 ++++++++++++++++++ ...eachability_try_catch_finally_A03_t03.dart | 77 +++++++++++++++++++ .../reachability_try_finally_A04_t02.dart | 47 +++++++++++ 5 files changed, 285 insertions(+) create mode 100644 TypeSystem/flow-analysis/reachability_try_catch_A03_t02.dart create mode 100644 TypeSystem/flow-analysis/reachability_try_catch_A04_t03.dart create mode 100644 TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t02.dart create mode 100644 TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t03.dart create mode 100644 TypeSystem/flow-analysis/reachability_try_finally_A04_t02.dart diff --git a/TypeSystem/flow-analysis/reachability_try_catch_A03_t02.dart b/TypeSystem/flow-analysis/reachability_try_catch_A03_t02.dart new file mode 100644 index 0000000000..df7f4af354 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_A03_t02.dart @@ -0,0 +1,49 @@ +// 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: If `N` is a try/catch statement of the form +/// `try B alternatives` then: +/// - Let `before(B) = before(N)` +/// - For each catch block on `Ti Si` in alternatives: +/// - Let +/// `before(Si) = conservativeJoin(before(N), assignedIn(B), capturedIn(B))` +/// - Let `after(N) = join(after(B), after(C0), ..., after(Ck))` +/// +/// @description Checks that if a type `T` is made a type of interest in `B` +/// then it can be promoted in `Si` and `after(N)`. +/// @author sgrekhov22@gmail.com +/// @issue 60519 + +// TODO (sgrekhov) https://github.com/dart-lang/language/issues/4328 + +class S {} + +class T extends S { + int answer() => 42; +} + +test1() { + S s = S(); + try { + if (s is T) {} // make `T` a type of interest + } on Exception catch (_) { + s = T(); + s.answer(); + } +} + +test2() { + S s = S(); + try { + if (s is T) {} + } catch (_) { + } + s = T(); + s.answer(); +} + +main() { + test1(); + test2(); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_A04_t03.dart b/TypeSystem/flow-analysis/reachability_try_catch_A04_t03.dart new file mode 100644 index 0000000000..7b128d29eb --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_A04_t03.dart @@ -0,0 +1,36 @@ +// 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: If `N` is a try/catch statement of the form +/// `try B alternatives` then: +/// - Let `before(B) = before(N)` +/// - For each catch block on `Ti Si` in alternatives: +/// - Let +/// `before(Si) = conservativeJoin(before(N), assignedIn(B), capturedIn(B))` +/// - Let `after(N) = join(after(B), after(C0), ..., after(Ck))` +/// +/// @description Checks that if `B` is empty and a type `T` is made a type of +/// interest in `alternatives` then it cannot be promoted in `after(N)`. +/// @author sgrekhov22@gmail.com + +// TODO (sgrekhov) https://github.com/dart-lang/language/issues/4328 + +class S {} + +class T extends S { + int answer() => 42; +} + +main() { + S s = S(); + try { + } on Exception catch (_) { + if (s is T) {} // Make `T` a type of interest + } + s = T(); + s.answer(); // ??? +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t02.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t02.dart new file mode 100644 index 0000000000..92527e48c5 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t02.dart @@ -0,0 +1,76 @@ +// 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 a type `T` is made a type of interest in `B1` +/// then it cannot be promoted in `Si`, `F` and `after(N)`. +/// @author sgrekhov22@gmail.com +/// @issue 60519 + +// TODO (sgrekhov) https://github.com/dart-lang/language/issues/4328 + +class S {} + +class T extends S { + int answer() => 42; +} + +class C { + T v; + C(this.v); +} + +test1() { + S s = S(); + try { + if (s is T) {} + } catch (_) { + s = T(); + s.answer(); +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } finally { + } +} + +test2() { + S s = S(); + try { + if (s is T) {} + } catch (_) { + } finally { + (x: s) = (x: T()); + s.answer(); +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test3() { + S s = S(); + try { + if (s is T) {} + } catch (_) { + } finally { + } + C(v: s) = C(T()); + s.answer(); // ??? Error or not? https://github.com/dart-lang/language/issues/4328 +} + +main() { + print(test1); + print(test2); + print(test3); +} diff --git a/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t03.dart b/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t03.dart new file mode 100644 index 0000000000..298902e3c6 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_catch_finally_A03_t03.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 a type `T` is made a type of interest in `Si` +/// then it cannot be promoted in `Sj`, where `i <> j` and `after(N)`. +/// @author sgrekhov22@gmail.com +/// @issue 60519 + +// TODO (sgrekhov) https://github.com/dart-lang/language/issues/4328 + +class S {} + +class T extends S { + int answer() => 42; +} + +class C { + T v; + C(this.v); +} + +test1() { + S s = S(); + try { + } on Exception catch (_) { + if (s is T) {} + } catch (_) { + s = T(); + s.answer(); +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } finally { + } +} + +test2() { + S s = S(); + try { + } on Exception catch (_) { + if (s is T) {} + } finally { + (x: s) = (x: T()); + s.answer(); +// ^^^^^^ +// [analyzer] unspecified +// [cfe] unspecified + } +} + +test3() { + S s = S(); + try { + } catch (_) { + if (s is T) {} + } finally { + } + C(v: s) = C(T()); + s.answer(); // ? https://github.com/dart-lang/language/issues/4328 +} + +main() { + print(test1); + print(test2); + print(test3); +} diff --git a/TypeSystem/flow-analysis/reachability_try_finally_A04_t02.dart b/TypeSystem/flow-analysis/reachability_try_finally_A04_t02.dart new file mode 100644 index 0000000000..992ec2aae1 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_try_finally_A04_t02.dart @@ -0,0 +1,47 @@ +// 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 finally: If `N` is a try/finally statement of the form +/// `try B1 finally B2` then: +/// - Let `before(B1) = split(before(N))` +/// - Let `before(B2) = split(join(drop(after(B1)), +/// conservativeJoin(before(N), assignedIn(B1), capturedIn(B1))))` +/// - Let `after(N) = restrict(after(B1), after(B2), assignedIn(B2))` +/// +/// @description Checks that if a type `T` is made a type of interest in `B1` +/// then it can be promoted in `B2` and `after(N)`. +/// @author sgrekhov22@gmail.com + +// TODO (sgrekhov) https://github.com/dart-lang/language/issues/4328 + +class S {} + +class T extends S { + int answer() => 42; +} + +test1() { + S s = S(); + try { + if (s is T) {} // Make `T` a type of interest + } finally { + s = T(); + s.answer(); + } +} + +test2() { + S s = S(); + try { + if (s is T) {} + } finally { + } + s = T(); + s.answer(); +} + +main() { + test1(); + test2(); +}