Skip to content
Snippets Groups Projects
Commit 3f64a0e3 authored by Ted Kremenek's avatar Ted Kremenek
Browse files

Fix crash in CFG construction for 'break' statements appearing in statement expressions

within the increment code of a for loop.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104375 91177308-0d34-0410-b5e6-96231b3b80d8
parent e0d5fe2a
No related branches found
No related tags found
No related merge requests found
......@@ -985,6 +985,11 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
} 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 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
{
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 @@ CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
// 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());
......
......@@ -450,3 +450,15 @@ int f26_nestedblocks() {
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}}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment