зеркало из https://github.com/microsoft/clang.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48322 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5518e7caf3
Коммит
4102af916d
21
AST/CFG.cpp
21
AST/CFG.cpp
|
@ -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";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Загрузка…
Ссылка в новой задаче