Skip to content

Commit

Permalink
[dart2wasm] Handle switches with just a default case
Browse files Browse the repository at this point in the history
Currently switch compiler looks at literals in alternatives to determine
how to check for equality.

When a switch statement only has a default case (no literals) the code
fails to determine the type of the expression in case statement and
assumes `bool`. Fixed by checking for these cases.

These tests now pass:

- co19/Language/Statements/Switch/syntax_t01
- co19/Language/Statements/Switch/execution_t02
- language/nnbd/flow_analysis/write_promoted_value_in_switch_test

Change-Id: If277b5a2dd04dd84d8d4ab6227d95c049d71f0e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/264681
Commit-Queue: Ömer Ağacan <[email protected]>
Reviewed-by: Joshua Litt <[email protected]>
  • Loading branch information
osa1 authored and Commit Queue committed Oct 26, 2022
1 parent 81ba8a2 commit 478f2bb
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions pkg/dart2wasm/lib/code_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1154,19 +1154,25 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
wrap(node.expression, voidMarker);
return;
}

bool check<L extends Expression, C extends Constant>() =>
node.cases.expand((c) => c.expressions).every((e) =>
e is L ||
e is NullLiteral ||
e is ConstantExpression &&
(e.constant is C || e.constant is NullConstant));
(e is ConstantExpression &&
(e.constant is C || e.constant is NullConstant)));

// Identify kind of switch. One of `nullableType` or `nonNullableType` will
// be the type for Wasm local that holds the switch value.
w.ValueType nullableType;
w.ValueType nonNullableType;
void Function() compare;
if (check<BoolLiteral, BoolConstant>()) {
late final w.ValueType nullableType;
late final w.ValueType nonNullableType;
late final void Function() compare;
if (node.cases.every((c) => c.expressions.isEmpty && c.isDefault)) {
// default-only switch
nonNullableType = w.RefType.eq(nullable: false);
nullableType = w.RefType.eq(nullable: true);
compare = () => throw "Comparison in default-only switch";
} else if (check<BoolLiteral, BoolConstant>()) {
// bool switch
nonNullableType = w.NumType.i32;
nullableType =
Expand Down

0 comments on commit 478f2bb

Please sign in to comment.