From 95fbe1949d8088d3d062a0c9857eb80a098729af Mon Sep 17 00:00:00 2001 From: sgrekhov Date: Mon, 28 Apr 2025 15:30:47 +0300 Subject: [PATCH 1/3] #3057. Add null-aware method invocation tests --- .../flow-analysis/reachability_A24_t01.dart | 38 +++++++++++++ .../flow-analysis/reachability_A24_t02.dart | 45 ++++++++++++++++ .../flow-analysis/reachability_A24_t03.dart | 53 +++++++++++++++++++ .../flow-analysis/reachability_A24_t04.dart | 47 ++++++++++++++++ .../flow-analysis/reachability_A24_t05.dart | 46 ++++++++++++++++ 5 files changed, 229 insertions(+) create mode 100644 TypeSystem/flow-analysis/reachability_A24_t01.dart create mode 100644 TypeSystem/flow-analysis/reachability_A24_t02.dart create mode 100644 TypeSystem/flow-analysis/reachability_A24_t03.dart create mode 100644 TypeSystem/flow-analysis/reachability_A24_t04.dart create mode 100644 TypeSystem/flow-analysis/reachability_A24_t05.dart diff --git a/TypeSystem/flow-analysis/reachability_A24_t01.dart b/TypeSystem/flow-analysis/reachability_A24_t01.dart new file mode 100644 index 0000000000..88869a02fb --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_A24_t01.dart @@ -0,0 +1,38 @@ +// 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 Null-aware method invocation +/// For now (April, 2025) the flow-analysis feature specification does not +/// specify the analysis of Null-aware method invocation. +/// +/// @description Checks that flow analysis doesn't promote to `Null`. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=sound-flow-analysis + +class C { + void foo(int x) {} +} + +test1(C? c) { + late int i; + if (c == null) { // This doesn't promote `c` to `Null` + c?.foo(i = 42); + } + i; // Possibly assigned +} + +test2(C? c) { + late int i; + if (c == null) { + c?..foo(i = 0) + ..foo(0); + } + i; +} + +main() { + print(test1); + print(test2); +} diff --git a/TypeSystem/flow-analysis/reachability_A24_t02.dart b/TypeSystem/flow-analysis/reachability_A24_t02.dart new file mode 100644 index 0000000000..4b530e7f95 --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_A24_t02.dart @@ -0,0 +1,45 @@ +// 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 Null-aware method invocation +/// For now (April, 2025) the flow-analysis feature specification does not +/// specify the analysis of Null-aware method invocation. +/// +/// @description Checks that is come variable is promoted to non-nullable then +/// null-aware method invocation is treated as a regular invocation. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=sound-flow-analysis + +class C { + void foo(int x) {} +} + +test1(C? c) { + int i; + if (c != null) { + c?.foo(i = 42); // ignore: invalid_null_aware_operator + } else { + i = 0; + } + i; // Definitely assigned +} + +test2(C? c) { + int i; + if (c != null) { + c?..foo(0) // ignore: invalid_null_aware_operator + ..foo(i = 42); + } else { + i = 1; + } + i; // Definitely assigned +} + +main() { + test1(C()); + test1(null); + test2(C()); + test2(null); +} diff --git a/TypeSystem/flow-analysis/reachability_A24_t03.dart b/TypeSystem/flow-analysis/reachability_A24_t03.dart new file mode 100644 index 0000000000..295eb0b5ed --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_A24_t03.dart @@ -0,0 +1,53 @@ +// Copyright (c) 2020, 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 Null-aware method invocation +/// For now (April, 2025) the flow-analysis feature specification does not +/// specify the analysis of Null-aware method invocation. +/// +/// @description Checks reachability after method call. Test return type `Never` +/// @author sgrekhov@unipro.ru + +// SharedOptions=--enable-experiment=sound-flow-analysis + +class C { + Never m1() => throw "Exception"; +} + +test1(C? c) { + try { + late int i; + if (c != null) { + c?.m1(); // ignore: invalid_null_aware_operator + i = 42; // This is dead code, which leaves `i` definitely unassigned. + } + i; // Definitely unassigned. +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } catch (_) { + } +} + +test2(C? c) { + try { + late int i; + if (c != null) { + c?..m1(); // ignore: invalid_null_aware_operator + i = 42; + } + i; +// ^ +// [analyzer] unspecified +// [cfe] unspecified + } catch (_) { + } +} + +main() { + test1(C()); + test1(null); + test2(C()); + test2(null); +} diff --git a/TypeSystem/flow-analysis/reachability_A24_t04.dart b/TypeSystem/flow-analysis/reachability_A24_t04.dart new file mode 100644 index 0000000000..3d58c368de --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_A24_t04.dart @@ -0,0 +1,47 @@ +// Copyright (c) 2020, 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 Null-aware method invocation +/// For now (April, 2025) the flow-analysis feature specification does not +/// specify the analysis of Null-aware method invocation. +/// +/// @description Checks reachability after method call. Test return type `Never` +/// @author sgrekhov@unipro.ru + +// SharedOptions=--enable-experiment=sound-flow-analysis + +class C { + Never m1() => throw "Exception"; +} + +test1(C? c) { + try { + late int i; + if (c == null) { // This doesn't promote `c` to `Null` + c?.m1(); + i = 42; + } + i; // Possibly assigned + } catch (_) { + } +} + +test2(C? c) { + try { + late int i; + if (c == null) { + c?..m1(); + i = 42; + } + i; + } catch (_) { + } +} + +main() { + test1(C()); + test1(null); + test2(C()); + test2(null); +} diff --git a/TypeSystem/flow-analysis/reachability_A24_t05.dart b/TypeSystem/flow-analysis/reachability_A24_t05.dart new file mode 100644 index 0000000000..17198e920b --- /dev/null +++ b/TypeSystem/flow-analysis/reachability_A24_t05.dart @@ -0,0 +1,46 @@ +// 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 Null-aware method invocation +/// For now (April, 2025) the flow-analysis feature specification does not +/// specify the analysis of Null-aware method invocation. +/// +/// @description Checks that +/// @author sgrekhov22@gmail.com +/// @issue 54820 + +// SharedOptions=--enable-experiment=sound-flow-analysis + +class C { + Never? get foo => throw "Exception"; +} + +test1() { + C c = C(); + late int i; + if (1 > 2) { + c.foo?.bar(i = 42); // ignore: receiver_of_type_never, dead_code + } + i; // Definitely unassigned +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +test2() { + C c = C(); + late int i; + if (1 > 2) { + c.foo?..bar(i = 0); // ignore: receiver_of_type_never, dead_code + } + i; +//^ +// [analyzer] unspecified +// [cfe] unspecified +} + +main() { + print(test1); + print(test2); +} From 245bfe84623d1732e2128f3a79b10f72a1e18634 Mon Sep 17 00:00:00 2001 From: sgrekhov Date: Mon, 28 Apr 2025 15:32:33 +0300 Subject: [PATCH 2/3] Fix description --- TypeSystem/flow-analysis/reachability_A24_t05.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TypeSystem/flow-analysis/reachability_A24_t05.dart b/TypeSystem/flow-analysis/reachability_A24_t05.dart index 17198e920b..87882499cb 100644 --- a/TypeSystem/flow-analysis/reachability_A24_t05.dart +++ b/TypeSystem/flow-analysis/reachability_A24_t05.dart @@ -6,7 +6,7 @@ /// For now (April, 2025) the flow-analysis feature specification does not /// specify the analysis of Null-aware method invocation. /// -/// @description Checks that +/// @description Checks that code after type `Never` is unreachable. /// @author sgrekhov22@gmail.com /// @issue 54820 From 2c8abef0665199b264077b9cc564b95577285dcf Mon Sep 17 00:00:00 2001 From: sgrekhov Date: Fri, 2 May 2025 13:38:53 +0300 Subject: [PATCH 3/3] Apply review suggestions --- .../flow-analysis/reachability_A24_t02.dart | 2 +- .../flow-analysis/reachability_A24_t04.dart | 30 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/TypeSystem/flow-analysis/reachability_A24_t02.dart b/TypeSystem/flow-analysis/reachability_A24_t02.dart index 4b530e7f95..db547c96e6 100644 --- a/TypeSystem/flow-analysis/reachability_A24_t02.dart +++ b/TypeSystem/flow-analysis/reachability_A24_t02.dart @@ -6,7 +6,7 @@ /// For now (April, 2025) the flow-analysis feature specification does not /// specify the analysis of Null-aware method invocation. /// -/// @description Checks that is come variable is promoted to non-nullable then +/// @description Checks that if a variable is promoted to non-nullable then /// null-aware method invocation is treated as a regular invocation. /// @author sgrekhov22@gmail.com diff --git a/TypeSystem/flow-analysis/reachability_A24_t04.dart b/TypeSystem/flow-analysis/reachability_A24_t04.dart index 3d58c368de..5bbf3d077b 100644 --- a/TypeSystem/flow-analysis/reachability_A24_t04.dart +++ b/TypeSystem/flow-analysis/reachability_A24_t04.dart @@ -16,27 +16,25 @@ class C { } test1(C? c) { - try { - late int i; - if (c == null) { // This doesn't promote `c` to `Null` - c?.m1(); - i = 42; - } - i; // Possibly assigned - } catch (_) { + int i; + if (c == null) { // This doesn't promote `c` to `Null` + c?.m1(); + i = 42; + } else { + i = 42; } + i; // Definitely assigned } test2(C? c) { - try { - late int i; - if (c == null) { - c?..m1(); - i = 42; - } - i; - } catch (_) { + late int i; + if (c == null) { + c?..m1(); + i = 42; + } else { + i = 42; } + i; } main() {