Fix a CFGBuilder bug exposed on convoluted control-flow in the Linux kernel.

llvm-svn: 126149
This commit is contained in:
Ted Kremenek 2011-02-21 22:11:26 +00:00
parent 93ede02045
commit 828f631af1
2 changed files with 21 additions and 5 deletions

View File

@ -928,11 +928,13 @@ CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
/// VisitChildren - Visit the children of a Stmt.
CFGBlock *CFGBuilder::VisitChildren(Stmt* Terminator) {
CFGBlock *B = Block;
for (Stmt::child_range I = Terminator->children(); I; ++I) {
if (*I) B = Visit(*I);
}
return B;
CFGBlock *lastBlock = Block;
for (Stmt::child_range I = Terminator->children(); I; ++I)
if (Stmt *child = *I)
if (CFGBlock *b = Visit(child))
lastBlock = b;
return lastBlock;
}
CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
@ -1819,6 +1821,7 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
if (badCFG)
return 0;
LoopSuccessor = Block;
Block = 0;
} else
LoopSuccessor = Succ;

View File

@ -1233,3 +1233,16 @@ void pr8648() {
// crash with assignment
y = ({ (union pr8648_union) { .pr8648_union_field = 0LL }; }).pr8648_union_field;
}
// PR 9269 - don't assert when building the following CFG. The for statement
// contains a condition with multiple basic blocks, and the value of the
// statement expression is then indexed as part of a bigger condition expression.
// This example exposed a bug in child traversal in the CFGBuilder.
void pr9269() {
struct s { char *bar[10]; } baz[2] = { 0 };
unsigned i = 0;
for (i = 0;
(* ({ while(0); ({ &baz[0]; }); })).bar[0] != 0;
++i) {}
}