]> granicus.if.org Git - clang/commitdiff
Fix a CFGBuilder bug exposed on convoluted control-flow in the Linux kernel.
authorTed Kremenek <kremenek@apple.com>
Mon, 21 Feb 2011 22:11:26 +0000 (22:11 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 21 Feb 2011 22:11:26 +0000 (22:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126149 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFG.cpp
test/Analysis/misc-ps.m

index a0ec5febbeff05a66db097526d4393273d14314f..0957875fd26866471113ff532b0d9b501d8b7158 100644 (file)
@@ -928,11 +928,13 @@ CFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) {
 
 /// VisitChildren - Visit the children of a Stmt.
 CFGBlock *CFGBuilder::VisitChildren(Stmt* Terminator) {
-  CFGBlock *B = Block;
-  for (Stmt::child_range I = Terminator->children(); I; ++I) {
-    if (*I) B = Visit(*I);
-  }
-  return B;
+  CFGBlock *lastBlock = Block;  
+  for (Stmt::child_range I = Terminator->children(); I; ++I)
+    if (Stmt *child = *I)
+      if (CFGBlock *b = Visit(child))
+        lastBlock = b;
+
+  return lastBlock;
 }
 
 CFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A,
@@ -1819,6 +1821,7 @@ CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
     if (badCFG)
       return 0;
     LoopSuccessor = Block;
+    Block = 0;
   } else
     LoopSuccessor = Succ;
 
index 45b44b7412c950ef3b72e6cbfa30020fcd9bb0a3..4daf899a8dc0fc47209947b672bcf020c7030548 100644 (file)
@@ -1233,3 +1233,16 @@ void pr8648() {
   // crash with assignment
   y = ({ (union pr8648_union) { .pr8648_union_field = 0LL }; }).pr8648_union_field;
 }
+
+// PR 9269 - don't assert when building the following CFG.  The for statement
+// contains a condition with multiple basic blocks, and the value of the
+// statement expression is then indexed as part of a bigger condition expression.
+// This example exposed a bug in child traversal in the CFGBuilder.
+void pr9269() {
+  struct s { char *bar[10]; } baz[2] = { 0 };
+  unsigned i = 0;
+  for (i = 0;
+  (* ({ while(0); ({ &baz[0]; }); })).bar[0] != 0;
+       ++i) {}
+}
+