[dart2wasm] Handle switches with just a default case

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 <omersa@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2022-10-26 16:50:28 +00:00 committed by Commit Queue
parent 81ba8a2583
commit 478f2bb34c

View file

@ -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 =