summaryrefslogtreecommitdiff
path: root/compiler/optimizing/graph_checker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/graph_checker.cc')
-rw-r--r--compiler/optimizing/graph_checker.cc28
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) {