]> granicus.if.org Git - clang/commitdiff
[-Wunreachable-code] add a specialized diagnostic for unreachable increment expressio...
authorTed Kremenek <kremenek@apple.com>
Fri, 21 Mar 2014 06:02:36 +0000 (06:02 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 21 Mar 2014 06:02:36 +0000 (06:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204430 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/Analyses/ReachableCode.h
include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Analysis/ReachableCode.cpp
lib/Sema/AnalysisBasedWarnings.cpp
test/SemaCXX/unreachable-code.cpp
test/SemaCXX/warn-unreachable.cpp
test/SemaObjC/warn-unreachable.m

index ed0d711aefb569e5db1395e74d7524fc60e45e71..a328ea2c8f95bdcb0d8e35bd138d00c015c07063 100644 (file)
@@ -41,6 +41,7 @@ namespace reachable_code {
 enum UnreachableKind {
   UK_Return,
   UK_Break,
+  UK_Loop_Increment,
   UK_Other
 };
 
index c7ea65fac7afe1a7081cb784668d795319a59b48..8066ed5a3ea717bb0cd8f7b061f72b763e9da4ad 100644 (file)
@@ -430,7 +430,9 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
 //  least actively used, with more noisy versions of the warning covered
 //  under separate flags.
 //
-def UnreachableCode : DiagGroup<"unreachable-code">;
+def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
+def UnreachableCode : DiagGroup<"unreachable-code",
+                                [UnreachableCodeLoopIncrement]>;
 def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
 def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
 def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
index 7bc66be8958bd55cd3776cc5de0d601859021a6d..5e459305126550441fb295d0511397d6e5e39f8b 100644 (file)
@@ -370,6 +370,9 @@ def warn_unreachable_break : Warning<
 def warn_unreachable_return : Warning<
   "'return' will never be executed">,
   InGroup<UnreachableCodeReturn>, DefaultIgnore;
+def warn_unreachable_loop_increment : Warning<
+  "loop will run at most once (loop increment never executed)">,
+  InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
 
 /// Built-in functions.
 def ext_implicit_lib_function_decl : ExtWarn<
index 4220000cd334794732a91bc20b7ca8cfefc2fdf1..53e03de64ed482d88374fd894f1362908d9d40ed 100644 (file)
@@ -529,6 +529,26 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
     UK = reachable_code::UK_Return;
   }
 
+  if (UK == reachable_code::UK_Other) {
+    // Check if the dead code is part of the "loop target" of
+    // a for/for-range loop.  This is the block that contains
+    // the increment code.
+    if (const Stmt *LoopTarget = B->getLoopTarget()) {
+      SourceLocation Loc = LoopTarget->getLocStart();
+      SourceRange R1(Loc, Loc), R2;
+
+      if (const ForStmt *FS = dyn_cast<ForStmt>(LoopTarget)) {
+        const Expr *Inc = FS->getInc();
+        Loc = Inc->getLocStart();
+        R2 = Inc->getSourceRange();
+      }
+
+      CB.HandleUnreachable(reachable_code::UK_Loop_Increment,
+                           Loc, SourceRange(Loc, Loc), R2);
+      return;
+    }
+  }
+
   SourceRange R1, R2;
   SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
   CB.HandleUnreachable(UK, Loc, R1, R2);
index 389109a11bc3a9dd1777ba27af44ed888d576b6f..ecf6d51ef1c8f9ec3b2cfe16c4f662c0b27a4a61 100644 (file)
@@ -76,6 +76,9 @@ namespace {
         case reachable_code::UK_Return:
           diag = diag::warn_unreachable_return;
           break;
+        case reachable_code::UK_Loop_Increment:
+          diag = diag::warn_unreachable_loop_increment;
+          break;
         case reachable_code::UK_Other:
           break;
       }
@@ -1688,7 +1691,8 @@ clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
   DefaultPolicy.enableCheckUnreachable =
     isEnabled(D, warn_unreachable) ||
     isEnabled(D, warn_unreachable_break) ||
-    isEnabled(D, warn_unreachable_return);
+    isEnabled(D, warn_unreachable_return) ||
+    isEnabled(D, warn_unreachable_loop_increment);
 
   DefaultPolicy.enableThreadSafetyAnalysis =
     isEnabled(D, warn_double_lock);
index 5016c3f24be98acc62fa51a2bd866d23a29a0899..fd006c099e7dc6b07a7e8efa0b3445b34bd85827 100644 (file)
@@ -5,7 +5,7 @@ int bar();
 int test1() {
   for (int i = 0;
        i != 10;
-       ++i) {  // expected-warning {{will never be executed}}
+       ++i) {  // expected-warning {{loop will run at most once (loop increment never executed)}}
     if (j == 23) // missing {}'s
       bar();
       return 1;
@@ -17,7 +17,7 @@ int test1() {
 int test1_B() {
   for (int i = 0;
        i != 10;
-       ++i) {  // expected-warning {{will never be executed}}
+       ++i) {  // expected-warning {{loop will run at most once (loop increment never executed)}}
     if (j == 23) // missing {}'s
       bar();
       return 1;
index eab8d8e6b97150e5cb876be70a71c41c6d0ece1b..8acaf428551808b28916469af86e96ffc3ef726f 100644 (file)
@@ -282,3 +282,15 @@ void test_static_class_var(Frodo &F) {
     somethingToCall(); // no-warning
 }
 
+void test_unreachable_for_null_increment() {
+  for (unsigned i = 0; i < 10 ; ) // no-warning
+    break;
+}
+
+void test_unreachable_forrange_increment() {
+  int x[10] = { 0 };
+  for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+    break;
+  }
+}
+
index 979b9053b3d92e0451fef36abf7439b3dde91bbb..859bd00f310b12db504897c0e3f613b45e028f0b 100644 (file)
@@ -40,3 +40,12 @@ int test_CONFIG() {
   else
     return 0;
 }
+
+// FIXME: This should at some point report a warning
+// that the loop increment is unreachable.
+void test_loop_increment(id container) {
+  for (id x in container) { // no-warning
+    break;
+  }
+}
+