[vm/compiler] Fix crash in inliner when receiver is dead

Fixes https://github.com/dart-lang/sdk/issues/42065

Change-Id: Ib66163a41a13f02cfa9df9bcb1cf505e934fea93
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149370
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2020-05-29 16:34:45 +00:00
committed by commit-bot@chromium.org
parent 6a551f8d54
commit f57c99fc31
3 changed files with 32 additions and 3 deletions
@@ -0,0 +1,22 @@
// 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.
// Verifies that compiler doesn't crash while inlining recognized method
// when receiver is a dead code.
// Regression test for https://github.com/dart-lang/sdk/issues/42065.
import "package:expect/expect.dart";
List<int> foo0(int par1) {
if (par1 >= 39) {
return <int>[];
}
throw 'hi';
}
main() {
Expect.throws(() {
(foo0(0)).add(42);
}, (e) => e == 'hi');
}
+7
View File
@@ -3658,6 +3658,13 @@ bool FlowGraphInliner::TryInlineRecognizedMethod(
Definition** result,
SpeculativeInliningPolicy* policy,
FlowGraphInliner::ExactnessInfo* exactness) {
if (receiver_cid == kNeverCid) {
// Receiver was defined in dead code and was replaced by the sentinel.
// Original receiver cid is lost, so don't try to inline recognized
// methods.
return false;
}
const bool can_speculate = policy->IsAllowedForInlining(call->deopt_id());
const MethodRecognizer::Kind kind = target.recognized_kind();
@@ -273,9 +273,9 @@ void InlineExitCollector::ReplaceCall(BlockEntryInstr* callee_entry) {
call_->previous()->AppendInstruction(branch);
call_block->set_last_instruction(branch);
// Replace uses of the return value with null to maintain valid
// SSA form - even though the rest of the caller is unreachable.
call_->ReplaceUsesWith(caller_graph_->constant_null());
// Replace uses of the return value with sentinel constant to maintain
// valid SSA form - even though the rest of the caller is unreachable.
call_->ReplaceUsesWith(caller_graph_->GetConstant(Object::sentinel()));
// Update dominator tree.
for (intptr_t i = 0, n = callee_entry->dominated_blocks().length(); i < n;