From 0b1d9b7557437176f9cea1283bfac2510812bece Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 27 Aug 2007 21:54:41 +0000 Subject: [PATCH] Added support for short-circuit '&&' and '||' operators in source-level CFGs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41520 91177308-0d34-0410-b5e6-96231b3b80d8 --- AST/CFG.cpp | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/AST/CFG.cpp b/AST/CFG.cpp index 203348f7f3..b79bfe519b 100644 --- a/AST/CFG.cpp +++ b/AST/CFG.cpp @@ -210,6 +210,37 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { Block->setTerminator(C); return addStmt(C->getCond()); } + + case Stmt::ParenExprClass: + return WalkAST(cast(S)->getSubExpr(),AlwaysAddStmt); + + case Stmt::BinaryOperatorClass: { + BinaryOperator* B = cast(S); + + if (B->isLogicalOp()) { // && or || + CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock(); + ConfluenceBlock->appendStmt(B); + FinishBlock(ConfluenceBlock); + + // create the block evaluating the LHS + CFGBlock* LHSBlock = createBlock(false); + LHSBlock->addSuccessor(ConfluenceBlock); + LHSBlock->setTerminator(B); + + // create the block evaluating the RHS + Succ = ConfluenceBlock; + Block = NULL; + CFGBlock* RHSBlock = Visit(B->getRHS()); + LHSBlock->addSuccessor(RHSBlock); + + // Generate the blocks for evaluating the LHS. + Block = LHSBlock; + return addStmt(B->getLHS()); + } + + // Fall through to the default case. + } + default: if (AlwaysAddStmt) Block->appendStmt(S); return WalkAST_VisitChildren(S); @@ -218,8 +249,7 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { /// WalkAST_VisitChildren - Utility method to call WalkAST on the /// children of a Stmt. -CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* S) -{ +CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* S) { CFGBlock* B = Block; for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ; I != E; ++I) @@ -833,11 +863,10 @@ public: OS << '\n'; } - void VisitConditionalOperator(ConditionalOperator* C) { - C->printPretty(OS); + void VisitExpr(Expr* E) { + E->printPretty(OS); OS << '\n'; - } - + } }; } // end anonymous namespace -- 2.40.0