Skip to content

Commit 1001acd

Browse files
authored
#3057. Add reachability tests for operators. Part 2. (#3099)
1 parent fe31e59 commit 1001acd

35 files changed

+1127
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that for an expression of the form `E1 % E2`
9+
/// `before(E2) = after(E1)`. Test that if `after(E1)` is unreachable then
10+
/// `before(E2)` is also unreachable.
11+
/// @author [email protected]
12+
13+
void test<T extends Never>(T n) {
14+
late int i;
15+
if (2 > 1) {
16+
n % (i = 42);
17+
}
18+
i; // Definitely unassigned
19+
//^
20+
// [analyzer] unspecified
21+
// [cfe] unspecified
22+
}
23+
24+
main() {
25+
print(test);
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that for an expression of the form `E1 % E2`
9+
/// `before(E2) = after(E1)`. Test that if `after(E1)` is unreachable then
10+
/// `before(E2)` is also unreachable.
11+
/// @author [email protected]
12+
13+
class C {
14+
int i;
15+
C(this.i);
16+
int operator %(int other) => i % other;
17+
}
18+
19+
void test<T extends Never>(T n) {
20+
late int i;
21+
if (2 > 1) {
22+
C(n) % (i = 42);
23+
}
24+
i; // Definitely unassigned
25+
//^
26+
// [analyzer] unspecified
27+
// [cfe] unspecified
28+
}
29+
30+
main() {
31+
print(test);
32+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 % E2` is `Never` `after(N) = unreachable(after(E2))`.
10+
/// @author [email protected]
11+
12+
class C<T extends Never> {
13+
T operator %(int other) => throw "";
14+
}
15+
16+
class C2<T extends Never> {
17+
Future<T> operator %(int other) async => throw "";
18+
}
19+
20+
void test1() {
21+
late int i;
22+
if (2 > 1) {
23+
C() % 2;
24+
i = 42;
25+
}
26+
i; // Definitely unassigned
27+
//^
28+
// [analyzer] unspecified
29+
// [cfe] unspecified
30+
}
31+
32+
void test2() {
33+
late int i;
34+
if (2 > 1) {
35+
C2() % 2;
36+
i = 42;
37+
}
38+
i; // Not definitely unassigned
39+
}
40+
41+
void test3() async {
42+
late int i;
43+
if (2 > 1) {
44+
await (C2() % 2);
45+
i = 42;
46+
}
47+
i; // Definitely unassigned
48+
//^
49+
// [analyzer] unspecified
50+
// [cfe] unspecified
51+
}
52+
53+
main() {
54+
print(test1);
55+
print(test2);
56+
print(test3);
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 % E2` is `Never` then `E2` is still reachable.
10+
/// @author [email protected]
11+
12+
class C<T extends Never> {
13+
T operator %(int x) => throw "C";
14+
}
15+
16+
main() {
17+
late int i;
18+
try {
19+
C() % (i = 42);
20+
} catch (_) {}
21+
i; // Not definitely unassigned
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 * E2` static type of `E1`is not `Never` then `after(N) = after(E2)`.
10+
/// This is tested by detecting that `i = 42` is considered to be guaranteed to
11+
/// have been executed when `i;` is executed.
12+
/// @author [email protected]
13+
14+
class C {
15+
int n;
16+
C(this.n);
17+
int operator %(int other) => n % other;
18+
}
19+
20+
main() {
21+
int i;
22+
C(1) % (i = 42);
23+
i; // Definitely assigned
24+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that for an expression of the form `E1 << E2`
9+
/// `before(E2) = after(E1)`. Test that if `after(E1)` is unreachable then
10+
/// `before(E2)` is also unreachable.
11+
/// @author [email protected]
12+
13+
void test<T extends Never>(T n) {
14+
late int i;
15+
if (2 > 1) {
16+
n << (i = 42);
17+
}
18+
i; // Definitely unassigned
19+
//^
20+
// [analyzer] unspecified
21+
// [cfe] unspecified
22+
}
23+
24+
main() {
25+
print(test);
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that for an expression of the form `E1 << E2`
9+
/// `before(E2) = after(E1)`. Test that if `after(E1)` is unreachable then
10+
/// `before(E2)` is also unreachable.
11+
/// @author [email protected]
12+
13+
class C {
14+
int i;
15+
C(this.i);
16+
int operator <<(int other) => i << other;
17+
}
18+
19+
void test<T extends Never>(T n) {
20+
late int i;
21+
if (2 > 1) {
22+
C(n) << (i = 42);
23+
}
24+
i; // Definitely unassigned
25+
//^
26+
// [analyzer] unspecified
27+
// [cfe] unspecified
28+
}
29+
30+
main() {
31+
print(test);
32+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 << E2` is `Never` `after(N) = unreachable(after(E2))`.
10+
/// @author [email protected]
11+
12+
class C<T extends Never> {
13+
T operator <<(int other) => throw "";
14+
}
15+
16+
class C2<T extends Never> {
17+
Future<T> operator <<(int other) async => throw "";
18+
}
19+
20+
void test1() {
21+
late int i;
22+
if (2 > 1) {
23+
C() << 2;
24+
i = 42;
25+
}
26+
i; // Definitely unassigned
27+
//^
28+
// [analyzer] unspecified
29+
// [cfe] unspecified
30+
}
31+
32+
void test2() {
33+
late int i;
34+
if (2 > 1) {
35+
C2() << 2;
36+
i = 42;
37+
}
38+
i; // Not definitely unassigned
39+
}
40+
41+
void test3() async {
42+
late int i;
43+
if (2 > 1) {
44+
await (C2() << 2);
45+
i = 42;
46+
}
47+
i; // Definitely unassigned
48+
//^
49+
// [analyzer] unspecified
50+
// [cfe] unspecified
51+
}
52+
53+
main() {
54+
print(test1);
55+
print(test2);
56+
print(test3);
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 << E2` is `Never` then `E2` is still reachable.
10+
/// @author [email protected]
11+
12+
class C<T extends Never> {
13+
T operator <<(int x) => throw "C";
14+
}
15+
16+
main() {
17+
late int i;
18+
try {
19+
C() << (i = 42);
20+
} catch (_) {}
21+
i; // Not definitely unassigned
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion - Binary operator: All binary operators other than `==`, `&&`,
6+
/// `||`, and `??` are handled as calls to the appropriate `operator` method.
7+
///
8+
/// @description Checks that if the static type of the expression of the form
9+
/// `E1 << E2` static type of `E1`is not `Never` then `after(N) = after(E2)`.
10+
/// This is tested by detecting that `i = 42` is considered to be guaranteed to
11+
/// have been executed when `i;` is executed.
12+
/// @author [email protected]
13+
14+
class C {
15+
int i;
16+
C(this.i);
17+
int operator <<(int other) => i << other;
18+
}
19+
20+
main() {
21+
int i;
22+
C(1) << (i = 42);
23+
i; // Definitely assigned
24+
}

0 commit comments

Comments
 (0)