Skip to content

Commit 11ea496

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,dart2wasm,tfa] Handle 'Never' static type as unreachable in TFA
When building a data flow summary, break control and data flow after invocations with static result type 'Never', expressing that code after such invocation is unreachable. TEST=pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart Issue: #59941 Change-Id: I2e5acd861e4192bae231d356aeacf921a14766f5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405443 Reviewed-by: Slava Egorov <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent bf35086 commit 11ea496

File tree

3 files changed

+39
-9
lines changed

3 files changed

+39
-9
lines changed

pkg/vm/lib/transformations/type_flow/summary_collector.dart

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,29 +1275,39 @@ class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
12751275
_declareVariable(decl, _typesBuilder.fromStaticType(decl.type, true));
12761276
}
12771277

1278-
Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args,
1278+
TypeExpr _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args,
12791279
{bool isInstanceCreation = false}) {
1280-
Type? staticResultType = null;
12811280
Member? target;
12821281
if (selector is DirectSelector) {
12831282
target = selector.member;
12841283
} else if (selector is InterfaceSelector) {
12851284
target = selector.member;
12861285
}
1287-
if (target is Procedure && node is Expression) {
1288-
final returnType = target.function.returnType;
1286+
Type? staticResultType = null;
1287+
if (node is Expression) {
12891288
final staticDartType = _staticDartType(node);
1290-
// TODO(dartbug.com/54200): static type cannot be trusted when
1291-
// function type is returned.
1292-
if (returnType is TypeParameterType ||
1293-
(returnType != staticDartType && returnType is! FunctionType)) {
1294-
staticResultType = _typesBuilder.fromStaticType(staticDartType, true);
1289+
if (staticDartType is NeverType &&
1290+
staticDartType.declaredNullability == Nullability.nonNullable) {
1291+
staticResultType = emptyType;
1292+
} else if (target is Procedure) {
1293+
final returnType = target.function.returnType;
1294+
// TODO(dartbug.com/54200): static type cannot be trusted when
1295+
// function type is returned.
1296+
if (returnType is TypeParameterType ||
1297+
(returnType != staticDartType && returnType is! FunctionType)) {
1298+
staticResultType = _typesBuilder.fromStaticType(staticDartType, true);
1299+
}
12951300
}
12961301
}
12971302
Call call = new Call(selector, args, staticResultType, isInstanceCreation);
12981303
call.condition = _currentCondition;
12991304
_summary.add(call);
13001305
callSites[node] = call;
1306+
if (staticResultType is EmptyType) {
1307+
_currentCondition = emptyType;
1308+
_variableValues = _makeEmptyVariableValues();
1309+
return emptyType;
1310+
}
13011311
return call;
13021312
}
13031313

pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,4 +324,15 @@ void cast1(x) {
324324
bar(x);
325325
}
326326

327+
void never1(bool cond) {
328+
int i = 1;
329+
if (cond) {
330+
i = 2;
331+
returnNever();
332+
}
333+
foo(i);
334+
}
335+
336+
Never returnNever() => throw 'bye';
337+
327338
main() {}

pkg/vm/testcases/transformations/type_flow/summary_collector/control_flow.dart.expect

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,15 @@ t1 = _TypeCheck (%x against #lib::C1) (for x as #lib::C1)
337337
t2 = _Call direct [#lib::foo] (t1)
338338
t3 = _Call direct [#lib::bar] (t1)
339339
RESULT: _T {}?
340+
------------ never1 ------------
341+
%cond = _Parameter #0 [_T (dart.core::bool)+]
342+
t1 = _Call direct [#lib::returnNever] () {%cond}
343+
t2 = Not (%cond)
344+
t3 = _Call direct [#lib::foo] (_T (dart.core::_Smi, 1)) {t2}
345+
RESULT: _T {}?
346+
------------ returnNever ------------
347+
348+
RESULT: _T {}
340349
------------ main ------------
341350

342351
RESULT: _T {}?

0 commit comments

Comments
 (0)