[cfe-commits] r104375 - in /cfe/trunk: lib/Analysis/CFG.cpp test/Analysis/dead-stores.c
Ted Kremenek
kremenek at apple.com
Fri May 21 13:30:15 PDT 2010
Author: kremenek
Date: Fri May 21 15:30:15 2010
New Revision: 104375
URL: http://llvm.org/viewvc/llvm-project?rev=104375&view=rev
Log:
Fix crash in CFG construction for 'break' statements appearing in statement expressions
within the increment code of a for loop.
Modified:
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/test/Analysis/dead-stores.c
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=104375&r1=104374&r2=104375&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri May 21 15:30:15 2010
@@ -985,6 +985,11 @@
} else
LoopSuccessor = Succ;
+ // Save the current value for the break targets.
+ // All breaks should go to the code following the loop.
+ SaveAndRestore<CFGBlock*> save_break(BreakTargetBlock);
+ BreakTargetBlock = LoopSuccessor;
+
// Because of short-circuit evaluation, the condition of the loop can span
// multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that
// evaluate the condition.
@@ -1032,10 +1037,9 @@
{
assert(F->getBody());
- // Save the current values for Block, Succ, and continue and break targets
- SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
- save_continue(ContinueTargetBlock),
- save_break(BreakTargetBlock);
+ // Save the current values for Block, Succ, and continue targets.
+ SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
+ save_continue(ContinueTargetBlock);
// Create a new block to contain the (bottom) of the loop body.
Block = NULL;
@@ -1065,9 +1069,6 @@
// represent the 'loop target' for looping back to the start of the loop.
ContinueTargetBlock->setLoopTarget(F);
- // All breaks should go to the code following the loop.
- BreakTargetBlock = LoopSuccessor;
-
// Now populate the body block, and in the process create new blocks as we
// walk the body of the loop.
CFGBlock* BodyBlock = addStmt(F->getBody());
Modified: cfe/trunk/test/Analysis/dead-stores.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dead-stores.c?rev=104375&r1=104374&r2=104375&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dead-stores.c (original)
+++ cfe/trunk/test/Analysis/dead-stores.c Fri May 21 15:30:15 2010
@@ -450,3 +450,15 @@
return y;
}
+// The FOREACH macro in QT uses 'break' statements within statement expressions
+// placed within the increment code of for loops.
+void rdar8014335() {
+ for (int i = 0 ; i != 10 ; ({ break; })) {
+ for ( ; ; ({ ++i; break; })) ;
+ // Note that the next value stored to 'i' is never executed
+ // because the next statement to be executed is the 'break'
+ // in the increment code of the first loop.
+ i = i * 3; // expected-warning{{Value stored to 'i' is never read}}
+ }
+}
+
More information about the cfe-commits
mailing list