]> granicus.if.org Git - clang/commitdiff
Small changes to UnreachableCodeChecker
authorTom Care <tom.care@uqconnect.edu.au>
Thu, 12 Aug 2010 23:01:06 +0000 (23:01 +0000)
committerTom Care <tom.care@uqconnect.edu.au>
Thu, 12 Aug 2010 23:01:06 +0000 (23:01 +0000)
- Added detection of Empty CFGBlocks (artificial blocks)
- Relaxed an assertion based on an incorrect assumption until further investigation

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

lib/Checker/UnreachableCodeChecker.cpp

index 432967e00c2b9bf0a48ebf07e7a45ec9dca0e324..fd98a7a75d2b7372fda6d94221e0515f8636cb6e 100644 (file)
@@ -41,6 +41,7 @@ private:
   static inline const Stmt *getUnreachableStmt(const CFGBlock *CB);
   void FindUnreachableEntryPoints(const CFGBlock *CB);
   static bool isInvalidPath(const CFGBlock *CB, const ParentMap &PM);
+  static inline bool isEmptyCFGBlock(const CFGBlock *CB);
 
   llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> reachable;
   llvm::SmallSet<unsigned, DEFAULT_CFGBLOCKS> visited;
@@ -66,8 +67,8 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
   CFG *C = 0;
   ParentMap *PM = 0;
   // Iterate over ExplodedGraph
-  for (ExplodedGraph::node_iterator I = G.nodes_begin(); I != G.nodes_end();
-      ++I) {
+  for (ExplodedGraph::node_iterator I = G.nodes_begin(), E = G.nodes_end();
+      I != E; ++I) {
     const ProgramPoint &P = I->getLocation();
     const LocationContext *LC = P.getLocationContext();
 
@@ -96,6 +97,10 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
     if (reachable.count(CB->getBlockID()))
       continue;
 
+    // Check if the block is empty (an artificial block)
+    if (isEmptyCFGBlock(CB))
+      continue;
+
     // Find the entry points for this block
     FindUnreachableEntryPoints(CB);
 
@@ -194,7 +199,12 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB,
 
   // Get the predecessor block's terminator conditon
   const Stmt *cond = pred->getTerminatorCondition();
-  assert(cond && "CFGBlock's predecessor has a terminator condition");
+
+  //assert(cond && "CFGBlock's predecessor has a terminator condition");
+  // The previous assertion is invalid in some cases (eg do/while). Leaving
+  // reporting of these situations on at the moment to help triage these cases.
+  if (!cond)
+    return false;
 
   // Run each of the checks on the conditions
   if (containsMacro(cond) || containsEnum(cond)
@@ -204,3 +214,10 @@ bool UnreachableCodeChecker::isInvalidPath(const CFGBlock *CB,
 
   return false;
 }
+
+// Returns true if the given CFGBlock is empty
+bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
+  return CB->getLabel() == 0       // No labels
+      && CB->size() == 0           // No statements
+      && CB->getTerminator() == 0; // No terminator
+}