]> granicus.if.org Git - clang/commitdiff
[CFG] Set the “loop target” (back edge) for VisitObjCForCollectionStmt loops
authorAnna Zaks <ganna@apple.com>
Sat, 22 Jun 2013 00:23:20 +0000 (00:23 +0000)
committerAnna Zaks <ganna@apple.com>
Sat, 22 Jun 2013 00:23:20 +0000 (00:23 +0000)
Add the back edge info by creating a basic block, marked as loop target. This is
consistent with how other loops are processed, but was omitted from
VisitObjCForCollectionStmt.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184617 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFG.cpp

index f48589518541294941d4a25feac504a3a337327b..14b8fd4a101995cb95097b48c64bfe1f5e455337 100644 (file)
@@ -2183,17 +2183,24 @@ CFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
   // Now create the true branch.
   {
     // Save the current values for Succ, continue and break targets.
-    SaveAndRestore<CFGBlock*> save_Succ(Succ);
+    SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ);
     SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget),
-        save_break(BreakJumpTarget);
+                               save_break(BreakJumpTarget);
 
+    // Add an intermediate block between the BodyBlock and the
+    // EntryConditionBlock to represent the "loop back" transition, for looping
+    // back to the head of the loop.
+    CFGBlock *LoopBackBlock = 0;
+    Succ = LoopBackBlock = createBlock();
+    LoopBackBlock->setLoopTarget(S);
+    
     BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
-    ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos);
+    ContinueJumpTarget = JumpTarget(Succ, ScopePos);
 
     CFGBlock *BodyBlock = addStmt(S->getBody());
 
     if (!BodyBlock)
-      BodyBlock = EntryConditionBlock; // can happen for "for (X in Y) ;"
+      BodyBlock = ContinueJumpTarget.block; // can happen for "for (X in Y) ;"
     else if (Block) {
       if (badCFG)
         return 0;