Skip to content

Commit

Permalink
dart-lang#3057. Add flow analysis tests for throw expression
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Feb 13, 2025
1 parent 5198824 commit b866c7d
Show file tree
Hide file tree
Showing 7 changed files with 481 additions and 0 deletions.
22 changes: 22 additions & 0 deletions TypeSystem/flow-analysis/reachability_A10_t01.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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 throw: If `N` is a throw expression of the form `throw E1`, then:
/// - Let `before(E1) = before(N)`
/// - Let `after(N) = unreachable(after(E1))`
///
/// @description Checks that a code after throw expression is unreachable.
/// @author [email protected]
main() {
late int i;
if ((() => false)()) {
throw "Dead code after this point";
i = 42; // Variable is initialized in a dead code. This leaves it definitely unassigned
}
i; // It is an error to read a local late variable when it is definitely unassigned.
//^
// [analyzer] unspecified
// [cfe] unspecified
}
78 changes: 78 additions & 0 deletions TypeSystem/flow-analysis/reachability_A10_t02.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 throw: If `N` is a throw expression of the form `throw E1`, then:
/// - Let `before(E1) = before(N)`
/// - Let `after(N) = unreachable(after(E1))`
///
/// @description Checks that a code after throw expression is unreachable. Test
/// collection literals.
/// @author [email protected]
test1() {
late int i;
if ((() => false)()) {
[
0,
throw "Dead code after this point",
i = 42 // Variable is initialized in a dead code. This leaves it definitely unassigned
];
}
i; // It is an error to read a local late variable when it is definitely unassigned.
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test2() {
late int i;
if ((() => false)()) {
<int>{
0,
throw "Dead code after this point",
i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test3() {
late int i;
if ((() => false)()) {
<String, int>{
"key1": 0,
"key2": throw "Dead code after this point",
"key3": i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test4() {
late int i;
if ((() => false)()) {
<int, String>{
0: "value1",
throw "Dead code after this point": "value2",
i = 42: "value3"
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

main() {
print(test1);
print(test2);
print(test3);
print(test4);
}
82 changes: 82 additions & 0 deletions TypeSystem/flow-analysis/reachability_A10_t03.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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 throw: If `N` is a throw expression of the form `throw E1`, then:
/// - Let `before(E1) = before(N)`
/// - Let `after(N) = unreachable(after(E1))`
///
/// @description Checks that a code after throw expression is unreachable. Test
/// collection literals.
/// @author [email protected]
test1() {
late int i;
if ((() => false)()) {
[
0,
if (throw "Dead code after this point")
i = 42,
i = 42
];
}
i; // It is an error to read a local late variable when it is definitely unassigned.
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test2() {
late int i;
if ((() => false)()) {
<int>{
0,
if (throw "Dead code after this point")
i = 42,
i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test3() {
late int i;
if ((() => false)()) {
<String, int>{
"key1": 0,
if (throw "Dead code after this point")
"key2": i = 42,
"key3": i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test4() {
late int i;
if ((() => false)()) {
<int, String>{
0: "value1",
if (throw "Dead code after this point")
i = 42: "value2",
i = 0: "value3"
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

main() {
print(test1);
print(test2);
print(test3);
print(test4);
}
78 changes: 78 additions & 0 deletions TypeSystem/flow-analysis/reachability_A10_t04.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 throw: If `N` is a throw expression of the form `throw E1`, then:
/// - Let `before(E1) = before(N)`
/// - Let `after(N) = unreachable(after(E1))`
///
/// @description Checks that a code after throw expression is unreachable. Test
/// `for(;;)` loop in list literals.
/// @author [email protected]
test1() {
late int i;
if ((() => false)()) {
[
0,
for (throw "Dead code after this point";;)
i = 42,
i = 42
];
}
i; // It is an error to read a local late variable when it is definitely unassigned.
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test2() {
late int i;
if ((() => false)()) {
[
0,
for (;throw "Dead code after this point";)
i = 42,
i = 42
];
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test3() {
late int i;
if ((() => false)()) {
[
0,
for (;; throw "Dead code after this statement")
1,
i = 42
];
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test4() {
late int i;
if ((() => false)()) {
[
0,
for (var j = 0; j < 0; throw "Not a dead code after this point")
i = 42
];
}
i; // Ok
}

main() {
print(test1);
print(test2);
print(test3);
print(test4);
}
78 changes: 78 additions & 0 deletions TypeSystem/flow-analysis/reachability_A10_t05.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 throw: If `N` is a throw expression of the form `throw E1`, then:
/// - Let `before(E1) = before(N)`
/// - Let `after(N) = unreachable(after(E1))`
///
/// @description Checks that a code after throw expression is unreachable. Test
/// `for(;;)` loop in set literals.
/// @author [email protected]
test1() {
late int i;
if ((() => false)()) {
<int>{
0,
for (throw "Dead code after this point";;)
i = 42,
i = 42
};
}
i; // It is an error to read a local late variable when it is definitely unassigned.
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test2() {
late int i;
if ((() => false)()) {
<int>{
0,
for (; throw "Dead code after this point";)
i = 42,
i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test3() {
late int i;
if ((() => false)()) {
<int>{
0,
for (;; throw "Dead code after this statement")
1,
i = 42
};
}
i;
//^
// [analyzer] unspecified
// [cfe] unspecified
}

test4() {
late int i;
if ((() => false)()) {
<int>{
0,
for (var j = 0; j < 0; throw "Not a dead code after this point")
i = 42,
};
}
i; // Ok
}

main() {
print(test1);
print(test2);
print(test3);
print(test4);
}
Loading

0 comments on commit b866c7d

Please sign in to comment.