koldaniel updated this revision to Diff 139953.

https://reviews.llvm.org/D33844

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/MiscTidyModule.cpp
  clang-tidy/misc/TerminatingContinueCheck.cpp
  clang-tidy/misc/TerminatingContinueCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-terminating-continue.rst
  test/clang-tidy/misc-terminating-continue.cpp

Index: test/clang-tidy/misc-terminating-continue.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-terminating-continue.cpp
@@ -0,0 +1,65 @@
+// RUN: %check_clang_tidy %s misc-terminating-continue %t
+
+void f() {
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [misc-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(false);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [misc-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(0);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [misc-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(nullptr);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [misc-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(__null);
+
+
+  do {
+    int x = 1;
+    if (x > 0) continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'continue' in loop with false condition is equivalent to 'break' [misc-terminating-continue]
+    // CHECK-FIXES: if (x > 0) break;
+  } while (false);
+}
+
+void g() {
+  do {
+    do {
+      continue;
+      int x = 1;
+    } while (1 == 1);
+  } while (false);
+
+  do {
+    for (int i = 0; i < 1; ++i) {
+      continue;
+      int x = 1;
+    }
+  } while (false);
+
+  do {
+    while (true) {
+      continue;
+      int x = 1;
+    }
+  } while (false);
+
+  int v[] = {1,2,3,34};
+  do {
+    for (int n : v) {
+      if (n>2) continue;
+    }
+  } while (false);
+}
Index: docs/clang-tidy/checks/misc-terminating-continue.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-terminating-continue.rst
@@ -0,0 +1,34 @@
+.. title:: clang-tidy - misc-terminating-continue
+
+misc-terminating-continue
+=========================
+
+Detects `do while` loops with a condition always evaluating to false that
+have a `continue` statement, as this `continue` terminates the loop
+effectively.
+
+.. code-block:: c++
+
+  Parser::TPResult Parser::TryParseProtocolQualifiers() {
+    assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
+    ConsumeToken();
+    do {
+      if (Tok.isNot(tok::identifier))
+        return TPResult::Error;
+      ConsumeToken();
+
+      if (Tok.is(tok::comma)) {
+        ConsumeToken();
+
+        //Terminating continue
+        continue;
+      }
+
+      if (Tok.is(tok::greater)) {
+        ConsumeToken();
+        return TPResult::Ambiguous;
+      }
+    } while (false);
+
+    return TPResult::Error;
+  }
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -149,6 +149,7 @@
    misc-non-copyable-objects
    misc-redundant-expression
    misc-static-assert
+   misc-terminating-continue
    misc-throw-by-value-catch-by-reference
    misc-unconventional-assign-operator
    misc-uniqueptr-reset-release
Index: clang-tidy/misc/TerminatingContinueCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/TerminatingContinueCheck.h
@@ -0,0 +1,36 @@
+//===--- TerminatingContinueCheck.h - clang-tidy-----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_TERMINATING_CONTINUE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_TERMINATING_CONTINUE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Checks if a 'continue' statement terminates the loop (i.e. the loop has
+///	a condition which always evaluates to false).
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-terminating-continue.html
+class TerminatingContinueCheck : public ClangTidyCheck {
+public:
+  TerminatingContinueCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_TERMINATING_CONTINUE_H
Index: clang-tidy/misc/TerminatingContinueCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/TerminatingContinueCheck.cpp
@@ -0,0 +1,50 @@
+//===--- TerminatingContinueCheck.cpp - clang-tidy-------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TerminatingContinueCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void TerminatingContinueCheck::registerMatchers(MatchFinder *Finder) {
+  const auto doWithFalse =
+      doStmt(hasCondition(ignoringImpCasts(
+                 anyOf(cxxBoolLiteral(equals(false)), integerLiteral(equals(0)),
+                       cxxNullPtrLiteralExpr(), gnuNullExpr()))),
+             equalsBoundNode("closestLoop"))
+          .bind("doWithFalseCond");
+
+  Finder->addMatcher(
+      continueStmt(anyOf(hasAncestor(forStmt().bind("closestLoop")),
+                         hasAncestor(cxxForRangeStmt().bind("closestLoop")),
+                         hasAncestor(whileStmt().bind("closestLoop")),
+                         hasAncestor(doStmt().bind("closestLoop"))),
+                   hasAncestor(doWithFalse))
+          .bind("continue"),
+      this);
+}
+
+void TerminatingContinueCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *ContStmt = Result.Nodes.getNodeAs<ContinueStmt>("continue");
+
+  auto Diag =
+      diag(ContStmt->getLocStart(),
+           "'continue' in loop with false condition is equivalent to 'break'");
+  Diag << FixItHint::CreateReplacement(ContStmt->getSourceRange(), "break");
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -16,6 +16,7 @@
 #include "NonCopyableObjects.h"
 #include "RedundantExpressionCheck.h"
 #include "StaticAssertCheck.h"
+#include "TerminatingContinueCheck.h"
 #include "ThrowByValueCatchByReferenceCheck.h"
 #include "UnconventionalAssignOperatorCheck.h"
 #include "UniqueptrResetReleaseCheck.h"
@@ -31,6 +32,8 @@
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
     CheckFactories.registerCheck<MisplacedConstCheck>("misc-misplaced-const");
+    CheckFactories.registerCheck<TerminatingContinueCheck>(
+        "misc-terminating-continue");
     CheckFactories.registerCheck<UnconventionalAssignOperatorCheck>(
         "misc-unconventional-assign-operator");
     CheckFactories.registerCheck<DefinitionsInHeadersCheck>(
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -5,6 +5,7 @@
   UnconventionalAssignOperatorCheck.cpp
   DefinitionsInHeadersCheck.cpp
   MiscTidyModule.cpp
+  TerminatingContinueCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NonCopyableObjects.cpp
   RedundantExpressionCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to