From b205ea18cb49fe86af507076bda35c31fa06202d Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Wed, 4 Jan 2023 15:26:34 +0000 Subject: [PATCH] [vm] Fix compiler crash when returning a value of uninitialized late variable from async function This change fixes CompileType::CanBeFuture() which previously attempted to use Class objects by class id without first checking if cid is internal. Cid can be internal (SentinelCid) when CompileType::CanBeFuture() is called for a return value of an async function when it is returning a value of an uninitialized late local variable (such Return instruction is unreachable). TEST=runtime/tests/vm/dart/regress_flutter117892_test.dart Fixes https://github.com/flutter/flutter/issues/117892 Change-Id: I63f0ca32d6246487f5c33d983cef9bd22aaa2fb8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/278094 Reviewed-by: Slava Egorov Commit-Queue: Alexander Markov --- .../vm/dart/regress_flutter117892_test.dart | 23 +++++++++++++++++++ .../vm/compiler/backend/type_propagator.cc | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 runtime/tests/vm/dart/regress_flutter117892_test.dart diff --git a/runtime/tests/vm/dart/regress_flutter117892_test.dart b/runtime/tests/vm/dart/regress_flutter117892_test.dart new file mode 100644 index 00000000000..1c3f6bd634b --- /dev/null +++ b/runtime/tests/vm/dart/regress_flutter117892_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2023, 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. + +// Verifies that compiler doesn't crash when uninitialized late variable +// (sentinel) is returned from an async function. +// Regression test for https://github.com/flutter/flutter/issues/117892. + +import 'package:expect/expect.dart'; + +foo() async { + late int x; + if (3 != 3) { + x = 42; + } + return x; +} + +main() { + foo().then((_) { + Expect.fail("Exception should be thrown."); + }, onError: (_) {}); +} diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc index a5396e48e62..61d2458c6c2 100644 --- a/runtime/vm/compiler/backend/type_propagator.cc +++ b/runtime/vm/compiler/backend/type_propagator.cc @@ -947,7 +947,8 @@ bool CompileType::CanBeFuture() { ObjectStore* object_store = isolate_group->object_store(); if (cid_ != kIllegalCid && cid_ != kDynamicCid) { - if ((cid_ == kNullCid) || (cid_ == kNeverCid)) { + if ((cid_ == kNullCid) || (cid_ == kNeverCid) || + IsInternalOnlyClassId(cid_) || cid_ == kTypeArgumentsCid) { return false; } const Class& cls = Class::Handle(isolate_group->class_table()->At(cid_));