Optimizing: Do not use range-based loop when inserting elements.

When we iterate over the elements of a container and we may
insert new elements into that container, it's wrong to use
the range-based loop.

Bug: 24133462
Change-Id: Iee35fbcf88ed3bcd6155cbeba09bd256032a16be
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 9772ee7..274a2a6 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -342,7 +342,10 @@
   ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().size(), /* expandable */ true);
 
   // Scan blocks and mark those which contain throwing instructions.
-  for (HBasicBlock* block : graph_->GetBlocks()) {
+  // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators
+  // can be invalidated. We remember the initial size to avoid iterating over the new blocks.
+  for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) {
+    HBasicBlock* block = graph_->GetBlocks()[block_id];
     bool can_throw = false;
     for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) {
       if (insn.Current()->CanThrow()) {
@@ -380,7 +383,10 @@
   //   (c) link the new blocks to corresponding exception handlers.
   // We cannot iterate only over blocks in `branch_targets_` because switch-case
   // blocks share the same dex_pc.
-  for (HBasicBlock* try_block : graph_->GetBlocks()) {
+  // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators
+  // can be invalidated. We remember the initial size to avoid iterating over the new blocks.
+  for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) {
+    HBasicBlock* try_block = graph_->GetBlocks()[block_id];
     // TryBoundary blocks are added at the end of the list and not iterated over.
     DCHECK(!try_block->IsSingleTryBoundary());