summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy
diff options
context:
space:
mode:
authorGabor Horvath <xazax.hun@gmail.com>2015-02-10 09:14:26 +0000
committerGabor Horvath <xazax.hun@gmail.com>2015-02-10 09:14:26 +0000
commitd4637fb433bdef381dbe2f6a973d3a33e42e5907 (patch)
tree8c5ef72803c2d21444ff76a417c705d91c830468 /clang-tools-extra/clang-tidy
parent256f7ecad446a65fb3b3aec8d6add902a2040dc5 (diff)
downloadbcm5719-llvm-d4637fb433bdef381dbe2f6a973d3a33e42e5907.tar.gz
bcm5719-llvm-d4637fb433bdef381dbe2f6a973d3a33e42e5907.zip
[clang-tidy] Checker for inaccurate use of erase() method.
Algorithms like remove() does not actually remove any element from the container but returns an iterator to the first redundant element at the end of the container. These redundant elements must be removed using the erase() method. This check warns when not all of the elements will be removed due to using an inappropriate overload. Reviewer: alexfh Differential Revision: http://reviews.llvm.org/D7496 llvm-svn: 228679
Diffstat (limited to 'clang-tools-extra/clang-tidy')
-rw-r--r--clang-tools-extra/clang-tidy/misc/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.cpp64
-rw-r--r--clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.h36
-rw-r--r--clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp3
4 files changed, 104 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index b68648b629e..1f2d9960a50 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -4,6 +4,7 @@ add_clang_library(clangTidyMiscModule
ArgumentCommentCheck.cpp
AssignOperatorSignatureCheck.cpp
BoolPointerImplicitConversion.cpp
+ InaccurateEraseCheck.cpp
InefficientAlgorithmCheck.cpp
MiscTidyModule.cpp
SwappedArgumentsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.cpp b/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.cpp
new file mode 100644
index 00000000000..033e0a15d87
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.cpp
@@ -0,0 +1,64 @@
+//===--- InaccurateEraseCheck.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 "InaccurateEraseCheck.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 {
+
+void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
+ const auto CheckForEndCall = hasArgument(
+ 1,
+ anyOf(constructExpr(has(memberCallExpr(callee(methodDecl(hasName("end"))))
+ .bind("InaccEndCall"))),
+ anything()));
+
+ Finder->addMatcher(
+ memberCallExpr(
+ on(hasType(namedDecl(matchesName("std::")))),
+ callee(methodDecl(hasName("erase"))), argumentCountIs(1),
+ hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
+ "std::(remove_if|remove|unique)"))),
+ CheckForEndCall).bind("InaccAlgCall"))),
+ unless(isInTemplateInstantiation())).bind("InaccErase"),
+ this);
+}
+
+void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MemberCall =
+ Result.Nodes.getNodeAs<CXXMemberCallExpr>("InaccErase");
+ const auto *EndExpr =
+ Result.Nodes.getNodeAs<CXXMemberCallExpr>("InaccEndCall");
+ const SourceLocation Loc = MemberCall->getLocStart();
+
+ FixItHint Hint;
+
+ if (!Loc.isMacroID() && EndExpr) {
+ const auto *AlgCall = Result.Nodes.getNodeAs<CallExpr>("InaccAlgCall");
+ std::string ReplacementText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(EndExpr->getSourceRange()),
+ *Result.SourceManager, Result.Context->getLangOpts());
+ const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+ AlgCall->getLocEnd(), 0, *Result.SourceManager,
+ Result.Context->getLangOpts());
+ Hint = FixItHint::CreateInsertion(EndLoc, ", " + ReplacementText);
+ }
+
+ diag(Loc, "this call will remove at most one item even when multiple items "
+ "should be removed")
+ << Hint;
+}
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.h b/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.h
new file mode 100644
index 00000000000..cde7320a2be
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/misc/InaccurateEraseCheck.h
@@ -0,0 +1,36 @@
+//===--- InaccurateEraseCheck.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_INACCURATE_ERASE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_INACCURATE_ERASE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// \brief Checks for inaccurate use of \c erase() method.
+///
+/// Algorithms like \c remove() do not actually remove any element from the
+/// container but return an iterator to the first redundant element at the end
+/// of the container. These redundant elements must be removed using the
+/// \c erase() method. This check warns when not all of the elements will be
+/// removed due to using an inappropriate overload.
+class InaccurateEraseCheck : public ClangTidyCheck {
+public:
+ InaccurateEraseCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_INACCURATE_ERASE_H
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index dfd5a49986b..a43efabcfd3 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -13,6 +13,7 @@
#include "ArgumentCommentCheck.h"
#include "AssignOperatorSignatureCheck.h"
#include "BoolPointerImplicitConversion.h"
+#include "InaccurateEraseCheck.h"
#include "InefficientAlgorithmCheck.h"
#include "SwappedArgumentsCheck.h"
#include "UndelegatedConstructor.h"
@@ -31,6 +32,8 @@ public:
"misc-assign-operator-signature");
CheckFactories.registerCheck<BoolPointerImplicitConversion>(
"misc-bool-pointer-implicit-conversion");
+ CheckFactories.registerCheck<InaccurateEraseCheck>(
+ "misc-inaccurate-erase");
CheckFactories.registerCheck<InefficientAlgorithmCheck>(
"misc-inefficient-algorithm");
CheckFactories.registerCheck<SwappedArgumentsCheck>(
OpenPOWER on IntegriCloud