Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit dd1c3a3

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[vm] Make async transform resilient in context of invalid type and never type of iterables
The CFE can invoke transformations despite having compile-time errors. The async transform was crashing the compiler if it hits for-in iterables that have an invalid type or never type. In case of an invalid type, the program has a compile-time error and won't be able to run propertly. So we'll replace the entire for-in with an invalid expression statement if the iterable is an invalid expression. In case of a never type, the program should compile fine, which this CL also fixes. This makes the newly added tests no longer result in DartkCrash but rather in a compile-time error (invalid expression) or runtime-error (never type). Closes dart-lang/sdk#45014 Change-Id: Ic50f68400b67b57dd4a2c0a125b08f0f3e0d8dd6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/188463 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 700ba71 commit dd1c3a3

24 files changed

+850
-286
lines changed
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE.md file.
4+
45
// @dart=2.9
6+
57
foo() async {
68
Bar x;
79
for (dynamic y in x.z) {}
8-
}
10+
}
11+
12+
main() {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// @dart = 2.9
22
foo() async {}
3+
main() {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// @dart = 2.9
22
foo() async {}
3+
main() {}

pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/general/async_method_with_invalid_type.dart:6:3: Error: 'Bar' isn't a type.
5+
// pkg/front_end/testcases/general/async_method_with_invalid_type.dart:8:3: Error: 'Bar' isn't a type.
66
// Bar x;
77
// ^^^
88
//
@@ -13,3 +13,4 @@ static method foo() → dynamic async {
1313
for (dynamic y in x.z) {
1414
}
1515
}
16+
static method main() → dynamic {}

pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.outline.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ import self as self;
33

44
static method foo() → dynamic async
55
;
6+
static method main() → dynamic
7+
;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/async_method_with_invalid_type.dart:8:3: Error: 'Bar' isn't a type.
6+
// Bar x;
7+
// ^^^
8+
//
9+
import self as self;
10+
import "dart:async" as asy;
11+
import "dart:core" as core;
12+
13+
static method foo() → dynamic /* originally async */ {
14+
final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
15+
core::bool* :is_sync = false;
16+
FutureOr<dynamic>* :return_value;
17+
(dynamic) →* dynamic :async_op_then;
18+
(core::Object*, core::StackTrace*) →* dynamic :async_op_error;
19+
core::int* :await_jump_var = 0;
20+
dynamic :await_ctx_var;
21+
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
22+
try {
23+
#L1:
24+
{
25+
invalid-type x;
26+
{
27+
core::Iterator<invalid-type>* :sync-for-iterator = x.z.{core::Iterable::iterator};
28+
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
29+
dynamic y = :sync-for-iterator.{core::Iterator::current};
30+
{}
31+
}
32+
}
33+
}
34+
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
35+
return;
36+
}
37+
on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
38+
asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
39+
}
40+
:async_op_then = asy::_asyncThenWrapperHelper(:async_op);
41+
:async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
42+
:async_op.call();
43+
:is_sync = true;
44+
return :async_future;
45+
}
46+
static method main() → dynamic {}

pkg/front_end/testcases/general/invalid_cast.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
4+
45
// @dart=2.9
6+
57
class C {
68
C();
79
factory C.fact() => null;

pkg/front_end/testcases/general/invalid_cast.dart.weak.expect

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,60 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/general/invalid_cast.dart:20:25: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
5+
// pkg/front_end/testcases/general/invalid_cast.dart:22:25: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
66
// - 'List' is from 'dart:core'.
77
// - 'Object' is from 'dart:core'.
88
// Change the type of the list literal or the context in which it is used.
99
// List<int> a = <Object>[];
1010
// ^
1111
//
12-
// pkg/front_end/testcases/general/invalid_cast.dart:21:40: Error: The map literal type 'Map<Object, String>' isn't of expected type 'Map<int, String>'.
12+
// pkg/front_end/testcases/general/invalid_cast.dart:23:40: Error: The map literal type 'Map<Object, String>' isn't of expected type 'Map<int, String>'.
1313
// - 'Map' is from 'dart:core'.
1414
// - 'Object' is from 'dart:core'.
1515
// Change the type of the map literal or the context in which it is used.
1616
// Map<int, String> b = <Object, String>{};
1717
// ^
1818
//
19-
// pkg/front_end/testcases/general/invalid_cast.dart:22:37: Error: The map literal type 'Map<int, Object>' isn't of expected type 'Map<int, String>'.
19+
// pkg/front_end/testcases/general/invalid_cast.dart:24:37: Error: The map literal type 'Map<int, Object>' isn't of expected type 'Map<int, String>'.
2020
// - 'Map' is from 'dart:core'.
2121
// - 'Object' is from 'dart:core'.
2222
// Change the type of the map literal or the context in which it is used.
2323
// Map<int, String> c = <int, Object>{};
2424
// ^
2525
//
26-
// pkg/front_end/testcases/general/invalid_cast.dart:23:28: Error: The function expression type 'int Function(int)' isn't of expected type 'int Function(Object)'.
26+
// pkg/front_end/testcases/general/invalid_cast.dart:25:28: Error: The function expression type 'int Function(int)' isn't of expected type 'int Function(Object)'.
2727
// - 'Object' is from 'dart:core'.
2828
// Change the type of the function expression or the context in which it is used.
2929
// int Function(Object) d = (int i) => i;
3030
// ^
3131
//
32-
// pkg/front_end/testcases/general/invalid_cast.dart:26:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
32+
// pkg/front_end/testcases/general/invalid_cast.dart:28:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
3333
// - 'C' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
3434
// - 'D' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
3535
// Change the type of the object being constructed or the context in which it is used.
3636
// D g = new C.nonFact();
3737
// ^
3838
//
39-
// pkg/front_end/testcases/general/invalid_cast.dart:27:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
39+
// pkg/front_end/testcases/general/invalid_cast.dart:29:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
4040
// - 'C' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
4141
// - 'D' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
4242
// Change the type of the object being constructed or the context in which it is used.
4343
// D h = new C.nonFact2();
4444
// ^
4545
//
46-
// pkg/front_end/testcases/general/invalid_cast.dart:28:31: Error: The static method has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
46+
// pkg/front_end/testcases/general/invalid_cast.dart:30:31: Error: The static method has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
4747
// - 'Object' is from 'dart:core'.
4848
// Change the type of the method or the context in which it is used.
4949
// void Function(Object) i = C.staticFunction;
5050
// ^
5151
//
52-
// pkg/front_end/testcases/general/invalid_cast.dart:29:29: Error: The top level function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
52+
// pkg/front_end/testcases/general/invalid_cast.dart:31:29: Error: The top level function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
5353
// - 'Object' is from 'dart:core'.
5454
// Change the type of the function or the context in which it is used.
5555
// void Function(Object) j = topLevelFunction;
5656
// ^
5757
//
58-
// pkg/front_end/testcases/general/invalid_cast.dart:30:29: Error: The local function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
58+
// pkg/front_end/testcases/general/invalid_cast.dart:32:29: Error: The local function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
5959
// - 'Object' is from 'dart:core'.
6060
// Change the type of the function or the context in which it is used.
6161
// void Function(Object) k = localFunction;
@@ -99,54 +99,54 @@ class D extends self::C {
9999
static method topLevelFunction(core::int* i) → void {}
100100
static method bad() → dynamic {
101101
function localFunction(core::int* i) → void {}
102-
core::List<core::int*>* a = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:20:25: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
102+
core::List<core::int*>* a = let final Never* #t1 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:22:25: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
103103
- 'List' is from 'dart:core'.
104104
- 'Object' is from 'dart:core'.
105105
Change the type of the list literal or the context in which it is used.
106106
List<int> a = <Object>[];
107107
^" in <core::Object*>[];
108-
core::Map<core::int*, core::String*>* b = let final Never* #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:21:40: Error: The map literal type 'Map<Object, String>' isn't of expected type 'Map<int, String>'.
108+
core::Map<core::int*, core::String*>* b = let final Never* #t2 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:23:40: Error: The map literal type 'Map<Object, String>' isn't of expected type 'Map<int, String>'.
109109
- 'Map' is from 'dart:core'.
110110
- 'Object' is from 'dart:core'.
111111
Change the type of the map literal or the context in which it is used.
112112
Map<int, String> b = <Object, String>{};
113113
^" in <core::Object*, core::String*>{};
114-
core::Map<core::int*, core::String*>* c = let final Never* #t3 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:22:37: Error: The map literal type 'Map<int, Object>' isn't of expected type 'Map<int, String>'.
114+
core::Map<core::int*, core::String*>* c = let final Never* #t3 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:24:37: Error: The map literal type 'Map<int, Object>' isn't of expected type 'Map<int, String>'.
115115
- 'Map' is from 'dart:core'.
116116
- 'Object' is from 'dart:core'.
117117
Change the type of the map literal or the context in which it is used.
118118
Map<int, String> c = <int, Object>{};
119119
^" in <core::int*, core::Object*>{};
120-
(core::Object*) →* core::int* d = let final Never* #t4 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:23:28: Error: The function expression type 'int Function(int)' isn't of expected type 'int Function(Object)'.
120+
(core::Object*) →* core::int* d = let final Never* #t4 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:25:28: Error: The function expression type 'int Function(int)' isn't of expected type 'int Function(Object)'.
121121
- 'Object' is from 'dart:core'.
122122
Change the type of the function expression or the context in which it is used.
123123
int Function(Object) d = (int i) => i;
124124
^" in (core::int* i) → core::int* => i;
125125
self::D* e = self::C::fact() as{TypeError} self::D*;
126126
self::D* f = new self::D::•() as{TypeError} self::D*;
127-
self::D* g = let final Never* #t5 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:26:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
127+
self::D* g = let final Never* #t5 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:28:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
128128
- 'C' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
129129
- 'D' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
130130
Change the type of the object being constructed or the context in which it is used.
131131
D g = new C.nonFact();
132132
^" in new self::C::nonFact();
133-
self::D* h = let final Never* #t6 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:27:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
133+
self::D* h = let final Never* #t6 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:29:13: Error: The constructor returns type 'C' that isn't of expected type 'D'.
134134
- 'C' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
135135
- 'D' is from 'pkg/front_end/testcases/general/invalid_cast.dart'.
136136
Change the type of the object being constructed or the context in which it is used.
137137
D h = new C.nonFact2();
138138
^" in new self::C::nonFact2();
139-
(core::Object*) →* void i = let final Never* #t7 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:28:31: Error: The static method has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
139+
(core::Object*) →* void i = let final Never* #t7 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:30:31: Error: The static method has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
140140
- 'Object' is from 'dart:core'.
141141
Change the type of the method or the context in which it is used.
142142
void Function(Object) i = C.staticFunction;
143143
^" in #C1;
144-
(core::Object*) →* void j = let final Never* #t8 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:29:29: Error: The top level function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
144+
(core::Object*) →* void j = let final Never* #t8 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:31:29: Error: The top level function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
145145
- 'Object' is from 'dart:core'.
146146
Change the type of the function or the context in which it is used.
147147
void Function(Object) j = topLevelFunction;
148148
^" in #C2;
149-
(core::Object*) →* void k = let final Never* #t9 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:30:29: Error: The local function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
149+
(core::Object*) →* void k = let final Never* #t9 = invalid-expression "pkg/front_end/testcases/general/invalid_cast.dart:32:29: Error: The local function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
150150
- 'Object' is from 'dart:core'.
151151
Change the type of the function or the context in which it is used.
152152
void Function(Object) k = localFunction;

0 commit comments

Comments
 (0)