Skip to content

Commit fb5fbf1

Browse files
natebiggsCommit Queue
authored andcommitted
[dart2wasm] Fix null checks being added on non-nullable value types.
Bug: #59840 Change-Id: Ifaac6430eabfee21e4971b3dd864e22f65c80adf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402980 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Nate Biggs <[email protected]>
1 parent a3917df commit fb5fbf1

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

pkg/dart2wasm/lib/code_generator.dart

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,20 +2561,25 @@ abstract class AstCodeGenerator
25612561

25622562
@override
25632563
w.ValueType visitNullCheck(NullCheck node, w.ValueType expectedType) {
2564-
return _nullCheck(node.operand, translator.throwNullCheckError);
2565-
}
2566-
2567-
w.ValueType _nullCheck(Expression operand, Procedure errorProcedure) {
2568-
w.ValueType operandType = translator.translateType(dartTypeOf(operand));
2564+
w.ValueType operandType =
2565+
translator.translateType(dartTypeOf(node.operand));
25692566
w.ValueType nonNullOperandType = operandType.withNullability(false);
2567+
2568+
// In rare cases the operand is non-nullable but TFA doesn't optimize away
2569+
// the null check. If the operand is an unboxed type, the br_on_non_null
2570+
// would fail to compile.
2571+
if (!operandType.nullable) {
2572+
translateExpression(node.operand, operandType);
2573+
return nonNullOperandType;
2574+
}
25702575
w.Label nullCheckBlock = b.block(const [], [nonNullOperandType]);
2571-
translateExpression(operand, operandType);
2576+
translateExpression(node.operand, operandType);
25722577

2573-
// We lower a null check to a br_on_non_null, throwing a [TypeError] in the
2574-
// null case.
2578+
// We lower a null check to a br_on_non_null, throwing a [TypeError] in
2579+
// the null case.
25752580
b.br_on_non_null(nullCheckBlock);
25762581
call(translator.stackTraceCurrent.reference);
2577-
call(errorProcedure.reference);
2582+
call(translator.throwNullCheckError.reference);
25782583
b.unreachable();
25792584
b.end();
25802585
return nonNullOperandType;
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+
void main() {
6+
test(something: 1.0, other: 1.0);
7+
}
8+
9+
void test({double? something, double? other}) {
10+
// This asserts prevents the null check below from being removed.
11+
assert(
12+
(something == null && other == null) ||
13+
(something != null && other != null),
14+
);
15+
16+
if (something != null) {
17+
print(something);
18+
// With assertions 'other' will be an unboxed double. Ensure there is no
19+
// null check added.
20+
print(other!);
21+
}
22+
}

0 commit comments

Comments
 (0)