]> granicus.if.org Git - clang/commitdiff
Fixed successor order for CFG basic blocks when handling: x && y. The bug
authorTed Kremenek <kremenek@apple.com>
Fri, 21 Dec 2007 19:49:00 +0000 (19:49 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 21 Dec 2007 19:49:00 +0000 (19:49 +0000)
is best explained by illustration:

[ B2 ]
     1: x
     T: [B2.1] && ...
   Predecessors (1): B4
   Successors (2): B3 B1

Block "B3" should be the block where we evaluate "y" when "x" evaluates to
true. Previously we had the successor list reversed. Now this behavior matches
with how we handle other conditional branches.

Thanks to Nuno Lopes for reporting this problem.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45288 91177308-0d34-0410-b5e6-96231b3b80d8

AST/CFG.cpp

index 1546079c92ab416b7782825e2c67dddeb97bd439..93230744e6fd1500fdbefa120bb1ef5029004060 100644 (file)
@@ -340,14 +340,23 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {
 
         // create the block evaluating the LHS
         CFGBlock* LHSBlock = createBlock(false);
-        LHSBlock->addSuccessor(ConfluenceBlock);
-        LHSBlock->setTerminator(B);        
+        LHSBlock->setTerminator(B);
         
         // create the block evaluating the RHS
         Succ = ConfluenceBlock;
         Block = NULL;
         CFGBlock* RHSBlock = Visit(B->getRHS());
-        LHSBlock->addSuccessor(RHSBlock);
+
+        // Now link the LHSBlock with RHSBlock.
+        if (B->getOpcode() == BinaryOperator::LOr) {
+          LHSBlock->addSuccessor(ConfluenceBlock);
+          LHSBlock->addSuccessor(RHSBlock);
+        }
+        else {
+          assert (B->getOpcode() == BinaryOperator::LAnd);
+          LHSBlock->addSuccessor(RHSBlock);
+          LHSBlock->addSuccessor(ConfluenceBlock);
+        }
         
         // Generate the blocks for evaluating the LHS.
         Block = LHSBlock;