Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang-tidy] Add terminating continue check
Patch by: Daniel Kolozsvari! Differential Revision: https://reviews.llvm.org/D33844 llvm-svn: 332223
- Loading branch information
Showing
8 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//===--- 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" | ||
#include "clang/Tooling/FixIt.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace bugprone { | ||
|
||
void TerminatingContinueCheck::registerMatchers(MatchFinder *Finder) { | ||
const auto doWithFalse = | ||
doStmt(hasCondition(ignoringImpCasts( | ||
anyOf(cxxBoolLiteral(equals(false)), integerLiteral(equals(0)), | ||
cxxNullPtrLiteralExpr(), gnuNullExpr()))), | ||
equalsBoundNode("closestLoop")); | ||
|
||
Finder->addMatcher( | ||
continueStmt(hasAncestor(stmt(anyOf(forStmt(), whileStmt(), | ||
cxxForRangeStmt(), 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'") | ||
<< tooling::fixit::createReplacement(*ContStmt, "break"); | ||
} | ||
|
||
} // namespace bugprone | ||
} // namespace tidy | ||
} // namespace clang |
36 changes: 36 additions & 0 deletions
36
clang-tools-extra/clang-tidy/bugprone/TerminatingContinueCheck.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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_BUGPRONE_TERMINATINGCONTINUECHECK_H | ||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TERMINATINGCONTINUECHECK_H | ||
|
||
#include "../ClangTidy.h" | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace bugprone { | ||
|
||
/// 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/bugprone-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 bugprone | ||
} // namespace tidy | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_TERMINATINGCONTINUECHECK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
clang-tools-extra/docs/clang-tidy/checks/bugprone-terminating-continue.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.. title:: clang-tidy - bugprone-terminating-continue | ||
|
||
bugprone-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++ | ||
|
||
void f() { | ||
do { | ||
// some code | ||
continue; // terminating continue | ||
// some other code | ||
} while(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
clang-tools-extra/test/clang-tidy/bugprone-terminating-continue.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// RUN: %check_clang_tidy %s bugprone-terminating-continue %t | ||
|
||
void f() { | ||
do { | ||
continue; | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-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' [bugprone-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' [bugprone-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' [bugprone-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' [bugprone-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); | ||
} |