diff options
author | Anna Zaks <ganna@apple.com> | 2013-06-22 00:23:20 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-06-22 00:23:20 +0000 |
commit | 56b4975badc59e355d0bfb866b689f7131cd66c0 (patch) | |
tree | 124b7a25751f2cfa4c1cb6321aa01d96fa34a906 | |
parent | 41bc0994c3446249236499395b002f7fad5d752d (diff) | |
download | bcm5719-llvm-56b4975badc59e355d0bfb866b689f7131cd66c0.tar.gz bcm5719-llvm-56b4975badc59e355d0bfb866b689f7131cd66c0.zip |
[CFG] Set the “loop target” (back edge) for VisitObjCForCollectionStmt loops
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.
llvm-svn: 184617
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index f4858951854..14b8fd4a101 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -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; |