[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 <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
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 0000000..1c3f6bd
--- /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 a5396e4..61d2458 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -947,7 +947,8 @@
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_));