mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-13 19:24:21 +00:00
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:
parent
0ceb8eb150
commit
b64d183803
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user