diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h index 217ab1ebdbb..ded5fa606f4 100644 --- a/runtime/vm/compiler/backend/compile_type.h +++ b/runtime/vm/compiler/backend/compile_type.h @@ -80,7 +80,13 @@ class CompileType : public ZoneAllocated { // abstract type. The pair is assumed to be coherent. static CompileType Create(intptr_t cid, const AbstractType& type); - CompileType CopyNonNullable() const { + // Return the non-nullable version of this type. + CompileType CopyNonNullable() { + if (IsNull()) { + // Represent a non-nullable null type (typically arising for + // unreachable values) as None. + return None(); + } return CompileType(kNonNullable, kIllegalCid, type_); } diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc index b5d2201fade..7062a357c4a 100644 --- a/runtime/vm/compiler/backend/flow_graph.cc +++ b/runtime/vm/compiler/backend/flow_graph.cc @@ -1559,7 +1559,13 @@ RedefinitionInstr* FlowGraph::EnsureRedefinition(Instruction* prev, } } RedefinitionInstr* redef = new RedefinitionInstr(new Value(original)); - redef->set_constrained_type(new CompileType(compile_type)); + + // Don't set the constrained type when the type is None(), which denotes an + // unreachable value (e.g. using value null after an explicit null check). + if (!compile_type.IsNone()) { + redef->set_constrained_type(new CompileType(compile_type)); + } + InsertAfter(prev, redef, NULL, FlowGraph::kValue); RenameDominatedUses(original, redef, redef); return redef; diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc index cb7360eacb2..6e70d926ecb 100644 --- a/runtime/vm/compiler/backend/type_propagator.cc +++ b/runtime/vm/compiler/backend/type_propagator.cc @@ -283,7 +283,7 @@ void FlowGraphTypePropagator::VisitCheckClassId(CheckClassIdInstr* check) { void FlowGraphTypePropagator::VisitCheckNull(CheckNullInstr* check) { Definition* receiver = check->value()->definition(); CompileType* type = TypeOf(receiver); - if (type->is_nullable() && !type->IsNull()) { + if (type->is_nullable()) { // Insert redefinition for the receiver to guard against invalid // code motion. EnsureMoreAccurateRedefinition(check, receiver, type->CopyNonNullable()); @@ -305,7 +305,7 @@ void FlowGraphTypePropagator::CheckNonNullSelector( if (target.IsNull()) { // If the selector is not defined on Null, we can propagate non-nullness. CompileType* type = TypeOf(receiver); - if (type->is_nullable() && !type->IsNull()) { + if (type->is_nullable()) { // Insert redefinition for the receiver to guard against invalid // code motion. EnsureMoreAccurateRedefinition(call, receiver, type->CopyNonNullable());