diff --git a/runtime/tests/vm/dart/regress_flutter63819_test.dart b/runtime/tests/vm/dart/regress_flutter63819_test.dart new file mode 100644 index 00000000000..56d24122d67 --- /dev/null +++ b/runtime/tests/vm/dart/regress_flutter63819_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Verify that 'is' test of a nullable type accepts null. +// Regression test for https://github.com/flutter/flutter/issues/63819. + +import 'package:expect/expect.dart'; + +abstract class A {} + +class B extends A {} + +class C extends A {} + +@pragma('vm:never-inline') +bool foo(A? x) { + if (x is C?) { + print('$x is C?'); + return true; + } + print('$x is not C?'); + return false; +} + +void main() { + B(); + C(); + Expect.isFalse(foo(B())); + Expect.isTrue(foo(null)); +} diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index d066f1193e7..5f51a5b384c 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -453,6 +453,12 @@ bool HierarchyInfo::InstanceOfHasClassRange(const AbstractType& type, intptr_t* lower_limit, intptr_t* upper_limit) { ASSERT(CompilerState::Current().is_aot()); + if (type.IsNullable()) { + // 'is' test for nullable types should accept null cid in addition to the + // class range. In most cases it is not possible to extend class range to + // include kNullCid. + return false; + } if (CanUseSubtypeRangeCheckFor(type)) { const Class& type_class = Class::Handle(thread()->zone(), type.type_class());