forked from OSchip/llvm-project
Fix a CFGBuilder bug exposed on convoluted control-flow in the Linux kernel.
llvm-svn: 126149
This commit is contained in:
parent
93ede02045
commit
828f631af1
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue