/// 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,
if (badCFG)
return 0;
LoopSuccessor = Block;
+ Block = 0;
} else
LoopSuccessor = Succ;
// 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) {}
+}
+