Added bandaid support in CFG construction for ObjCForEachStmt and ObjCAtTryStmt:

we gracefully back out and return NULL for the CFG, allowing clients to skip
analyzing functions with these CFGs. We will add support later.

Modified base ASTConsumer "CFGVisitor" to detect when a CFG is not constructed
and to emit a warning.

llvm-svn: 48322
This commit is contained in:
Ted Kremenek 2008-03-13 03:04:22 +00:00
parent 0ceb8eb150
commit b64d183803
2 changed files with 28 additions and 2 deletions

View File

@ -113,6 +113,18 @@ public:
CFGBlock* VisitDefaultStmt(DefaultStmt* D);
CFGBlock* VisitIndirectGotoStmt(IndirectGotoStmt* I);
// FIXME: Add support for ObjC-specific control-flow structures.
CFGBlock* VisitObjCForCollectionStmt(ObjCForCollectionStmt* S) {
badCFG = true;
return Block;
}
CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
badCFG = true;
return Block;
}
private:
CFGBlock* createBlock(bool add_successor = true);
CFGBlock* addStmt(Stmt* S);
@ -122,6 +134,7 @@ private:
CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S);
void FinishBlock(CFGBlock* B);
bool badCFG;
};
/// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can
@ -133,6 +146,8 @@ CFG* CFGBuilder::buildCFG(Stmt* Statement) {
assert (cfg);
if (!Statement) return NULL;
badCFG = false;
// Create an empty block that will serve as the exit block for the CFG.
// Since this is the first block added to the CFG, it will be implicitly
// registered as the exit block.
@ -186,6 +201,12 @@ CFG* CFGBuilder::buildCFG(Stmt* Statement) {
// Create an empty entry block that has no predecessors.
cfg->setEntry(createBlock());
if (badCFG) {
delete cfg;
cfg = NULL;
return NULL;
}
// NULL out cfg so that repeated calls to the builder will fail and that
// the ownership of the constructed CFG is passed to the caller.
CFG* t = cfg;

View File

@ -482,8 +482,13 @@ void CFGVisitor::HandleTopLevelDecl(Decl *D) {
}
CFG *C = CFG::buildCFG(FD->getBody());
VisitCFG(*C, *FD);
delete C;
if (C) {
VisitCFG(*C, *FD);
delete C;
}
else
llvm::cerr << "warning: CFG could not be constructed.\n";
}
//===----------------------------------------------------------------------===//