diff options
| author | Ted Kremenek <kremenek@apple.com> | 2007-09-11 21:29:43 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2007-09-11 21:29:43 +0000 |
| commit | 3dd952ba7230409b189937575a9c0912de3cbb87 (patch) | |
| tree | 8817751db603e517962e1be384be0a951ecadf6d | |
| parent | f2fb4ad08e669dfc46baf677b7e22388114526e5 (diff) | |
| download | bcm5719-llvm-3dd952ba7230409b189937575a9c0912de3cbb87.tar.gz bcm5719-llvm-3dd952ba7230409b189937575a9c0912de3cbb87.zip | |
Fixed bug where ternary expressions and GCC-style conditional expressions
where not reversing the order of their subexpression blocks.
Added feature where CallExprs are placed in their own statement slot in
a CFGBlock. Thus we have a designated "return site" within a CFGBlock when
reasoning about function calls.
llvm-svn: 41866
| -rw-r--r-- | clang/AST/CFG.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/clang/AST/CFG.cpp b/clang/AST/CFG.cpp index 93ee6f449dc..c1f96ceed32 100644 --- a/clang/AST/CFG.cpp +++ b/clang/AST/CFG.cpp @@ -116,6 +116,7 @@ private: CFGBlock* WalkAST_VisitChildren(Stmt* S); CFGBlock* WalkAST_VisitVarDecl(VarDecl* D); CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S); + CFGBlock* WalkAST_VisitCallExpr(CallExpr* C); void FinishBlock(CFGBlock* B); }; @@ -231,10 +232,12 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { Succ = ConfluenceBlock; Block = NULL; CFGBlock* LHSBlock = Visit(C->getLHS()); + FinishBlock(LHSBlock); Succ = ConfluenceBlock; Block = NULL; CFGBlock* RHSBlock = Visit(C->getRHS()); + FinishBlock(RHSBlock); Block = createBlock(false); Block->addSuccessor(LHSBlock); @@ -253,10 +256,12 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { Succ = ConfluenceBlock; Block = NULL; CFGBlock* LHSBlock = Visit(C->getLHS()); - + FinishBlock(LHSBlock); + Succ = ConfluenceBlock; Block = NULL; CFGBlock* RHSBlock = Visit(C->getRHS()); + FinishBlock(RHSBlock); Block = createBlock(false); Block->addSuccessor(LHSBlock); @@ -279,6 +284,9 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { if (AlwaysAddStmt) Block->appendStmt(S); return Block; } + + case Stmt::CallExprClass: + return WalkAST_VisitCallExpr(cast<CallExpr>(S)); case Stmt::StmtExprClass: return WalkAST_VisitStmtExpr(cast<StmtExpr>(S)); @@ -358,6 +366,14 @@ CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* S) { return VisitCompoundStmt(S->getSubStmt()); } +/// WalkAST_VisitCallExpr - Utility method to handle function calls that +/// are nested in expressions. The idea is that each function call should +/// appear as a distinct statement in the CFGBlock. +CFGBlock* CFGBuilder::WalkAST_VisitCallExpr(CallExpr* C) { + Block->appendStmt(C); + return WalkAST_VisitChildren(C); +} + /// VisitStmt - Handle statements with no branching control flow. CFGBlock* CFGBuilder::VisitStmt(Stmt* Statement) { // We cannot assume that we are in the middle of a basic block, since @@ -458,6 +474,7 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) { // newly created blocks will be pointed to be "Block". return addStmt(I->getCond()); } + CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) { // If we were in the middle of a block we stop processing that block |

