[cfe-commits] r126149 - in /cfe/trunk: lib/Analysis/CFG.cpp test/Analysis/misc-ps.m

Ted Kremenek kremenek at apple.com
Mon Feb 21 14:11:26 PST 2011


Author: kremenek
Date: Mon Feb 21 16:11:26 2011
New Revision: 126149

URL: http://llvm.org/viewvc/llvm-project?rev=126149&view=rev
Log:
Fix a CFGBuilder bug exposed on convoluted control-flow in the Linux kernel.

Modified:
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/test/Analysis/misc-ps.m

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=126149&r1=126148&r2=126149&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Mon Feb 21 16:11:26 2011
@@ -928,11 +928,13 @@
 
 /// 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 @@
     if (badCFG)
       return 0;
     LoopSuccessor = Block;
+    Block = 0;
   } else
     LoopSuccessor = Succ;
 

Modified: cfe/trunk/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=126149&r1=126148&r2=126149&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps.m (original)
+++ cfe/trunk/test/Analysis/misc-ps.m Mon Feb 21 16:11:26 2011
@@ -1233,3 +1233,16 @@
   // 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) {}
+}
+





More information about the cfe-commits mailing list