From cf57f882ca8610ce41d35546b0c9ceea271e7b4f Mon Sep 17 00:00:00 2001 From: Nicholas Shahan Date: Fri, 10 Jul 2020 17:42:55 +0000 Subject: [PATCH] [ddc] Change `!` failure to a throw TypeError Fixes test failures in language/unsorted/inv_cse_licm_test Change-Id: If8df024d0128568e1f65463d4a82fa593b5a6a1d Fixes: https://github.com/dart-lang/sdk/issues/42443 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153481 Reviewed-by: Mark Zhou Commit-Queue: Nicholas Shahan --- pkg/dev_compiler/lib/src/kernel/compiler.dart | 3 ++- .../private/ddc_runtime/operations.dart | 25 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index d6f0fa523cc6..4ed43fadc9ae 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -5212,8 +5212,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor @override js_ast.Expression visitNullCheck(NullCheck node) { var expr = node.operand; + var jsExpr = _visitExpression(expr); // If the expression is non-nullable already, this is a no-op. - return isNullable(expr) ? notNull(expr) : _visitExpression(expr); + return isNullable(expr) ? runtimeCall('nullCheck(#)', [jsExpr]) : jsExpr; } @override diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index fd9a7d40ecf4..fefa3b8252f1 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -474,7 +474,9 @@ asInt(obj) { asNullableInt(obj) => obj == null ? null : asInt(obj); -/// Checks that `x` is not null or undefined. +/// Checks for null or undefined and returns [x]. +/// +/// Throws [NoSuchMethodError] when it is null or undefined. // // TODO(jmesserly): inline this, either by generating it as a function into // the module, or via some other pattern such as: @@ -487,12 +489,13 @@ _notNull(x) { return x; } -/// Checks that `x` is not null or undefined. +/// Checks for null or undefined and returns [x]. +/// +/// Throws a [TypeError] when [x] is null or undefined (under sound null safety +/// mode) or emits a runtime warning (otherwise). /// -/// Unlike `_notNull`, this throws a `CastError` (under strict checking) -/// or emits a runtime warning (otherwise). This is only used by the -/// compiler when casting from nullable to non-nullable variants of the -/// same type. +/// This is only used by the compiler when casting from nullable to non-nullable +/// variants of the same type. nullCast(x, type) { if (x == null) { if (!strictNullSafety) { @@ -504,6 +507,16 @@ nullCast(x, type) { return x; } +/// Checks for null or undefined and returns [x]. +/// +/// Throws a [TypeError] when [x] is null or undefined. +/// +/// This is only used by the compiler for the runtime null check operator `!`. +nullCheck(x) { + if (x == null) throw TypeErrorImpl("Unexpected null value."); + return x; +} + /// The global constant map table. final constantMaps = JS('!', 'new Map()');