]> granicus.if.org Git - clang/commitdiff
UnreachableCodeChecker cleanup and improvements
authorTom Care <tom.care@uqconnect.edu.au>
Wed, 6 Oct 2010 23:02:25 +0000 (23:02 +0000)
committerTom Care <tom.care@uqconnect.edu.au>
Wed, 6 Oct 2010 23:02:25 +0000 (23:02 +0000)
- Fixed some iterator style issues
- Don't process blocks that have been visited already
- Fixed a case where a unreachable block cycle was not reported
- Minor test case changes
- Added one test case from flow-sensitive version of the check. More coming.

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

lib/Checker/UnreachableCodeChecker.cpp
test/Analysis/unreachable-code-path.c

index 52fb0caba084b8f2c113c95656e0744837719b9e..68542197147cf039b87bf6ecad459fd5afa86dd6 100644 (file)
@@ -91,7 +91,7 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
   ASTContext &Ctx = B.getContext();
 
   // Find CFGBlocks that were not covered by any node
-  for (CFG::const_iterator I = C->begin(); I != C->end(); ++I) {
+  for (CFG::const_iterator I = C->begin(), E = C->end(); I != E; ++I) {
     const CFGBlock *CB = *I;
     // Check if the block is unreachable
     if (reachable.count(CB->getBlockID()))
@@ -102,7 +102,8 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
       continue;
 
     // Find the entry points for this block
-    FindUnreachableEntryPoints(CB);
+    if (!visited.count(CB->getBlockID()))
+      FindUnreachableEntryPoints(CB);
 
     // This block may have been pruned; check if we still want to report it
     if (reachable.count(CB->getBlockID()))
@@ -149,28 +150,19 @@ void UnreachableCodeChecker::VisitEndAnalysis(ExplodedGraph &G,
 
 // Recursively finds the entry point(s) for this dead CFGBlock.
 void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB) {
-  bool allPredecessorsReachable = true;
-
   visited.insert(CB->getBlockID());
 
-  for (CFGBlock::const_pred_iterator I = CB->pred_begin(); I != CB->pred_end();
-      ++I) {
-    // Recurse over all unreachable blocks
+  for (CFGBlock::const_pred_iterator I = CB->pred_begin(), E = CB->pred_end();
+      I != E; ++I) {
     if (!reachable.count((*I)->getBlockID())) {
-      // At least one predeccessor was unreachable
-      allPredecessorsReachable = false;
-
-      // Only visit the block once
+      // If we find an unreachable predecessor, mark this block as reachable so
+      // we don't report this block
+      reachable.insert(CB->getBlockID());
       if (!visited.count((*I)->getBlockID()))
+        // If we haven't previously visited the unreachable predecessor, recurse
         FindUnreachableEntryPoints(*I);
     }
   }
-
-  // If at least one predecessor is unreachable, mark this block as reachable
-  // so we don't report this block.
-  if (!allPredecessorsReachable) {
-    reachable.insert(CB->getBlockID());
-  }
 }
 
 // Find the Stmt* in a CFGBlock for reporting a warning
index 071532739cbe749f205bcdd097c961d3347bd932..acc30f43349c32fdd6d3b861ae46aec0cd341262 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -verify -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
 
 extern void foo(int a);
 
@@ -93,8 +93,8 @@ void test9(unsigned a) {
   switch (a) {
     if (a) // expected-warning{{never executed}}
       foo(a + 5); // no-warning
-    else // no-warning
-      foo(a); // no-warning
+    else          // no-warning
+      foo(a);     // no-warning
     case 1:
     case 2:
       break;
@@ -102,3 +102,23 @@ void test9(unsigned a) {
       break;
   }
 }
+
+// Tests from flow-sensitive version
+void test10() {
+  goto c;
+  d:
+  goto e; // expected-warning {{never executed}}
+  c: ;
+  int i;
+  return;
+  goto b; // expected-warning {{never executed}}
+  goto a; // expected-warning {{never executed}}
+  b:
+  i = 1; // expected-warning {{Value stored to 'i' is never read}}
+  a:
+  i = 2; // expected-warning {{Value stored to 'i' is never read}}
+  goto f;
+  e:
+  goto d;
+  f: ;
+}