diff options
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 6d0bdbe19b..2fe5b07b19 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -606,6 +606,34 @@ void SSAChecker::VisitInstruction(HInstruction* instruction) { instruction->GetId())); } } + + if (instruction->CanThrowIntoCatchBlock()) { + // Find the top-level environment. This corresponds to the environment of + // the catch block since we do not inline methods with try/catch. + HEnvironment* environment = instruction->GetEnvironment(); + while (environment->GetParent() != nullptr) { + environment = environment->GetParent(); + } + + // Find all catch blocks and test that `instruction` has an environment + // value for each one. + const HTryBoundary& entry = instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry(); + for (HBasicBlock* catch_block : entry.GetExceptionHandlers()) { + for (HInstructionIterator phi_it(catch_block->GetPhis()); !phi_it.Done(); phi_it.Advance()) { + HPhi* catch_phi = phi_it.Current()->AsPhi(); + if (environment->GetInstructionAt(catch_phi->GetRegNumber()) == nullptr) { + AddError(StringPrintf("Instruction %s:%d throws into catch block %d " + "with catch phi %d for vreg %d but its " + "corresponding environment slot is empty.", + instruction->DebugName(), + instruction->GetId(), + catch_block->GetBlockId(), + catch_phi->GetId(), + catch_phi->GetRegNumber())); + } + } + } + } } static Primitive::Type PrimitiveKind(Primitive::Type type) { |