aboutsummaryrefslogtreecommitdiff
path: root/clang-tidy/readability
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2018-01-30 14:55:50 +0000
committerAlexander Kornienko <alexfh@google.com>2018-01-30 14:55:50 +0000
commit13f62172d70a89a2f7c9c68c45aab7c7fe62b6e2 (patch)
treec20c72ce9905f743145625af5d261dd85c7900bd /clang-tidy/readability
parent8a3a9295153fdf95f16415c8d7742f07feec8dde (diff)
clang-tidy/rename_check.py misc-string-compare readability-string-compare
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@323766 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/readability')
-rw-r--r--clang-tidy/readability/CMakeLists.txt1
-rw-r--r--clang-tidy/readability/ReadabilityTidyModule.cpp3
-rw-r--r--clang-tidy/readability/StringCompareCheck.cpp82
-rw-r--r--clang-tidy/readability/StringCompareCheck.h36
4 files changed, 122 insertions, 0 deletions
diff --git a/clang-tidy/readability/CMakeLists.txt b/clang-tidy/readability/CMakeLists.txt
index a130c9b4..95769ee9 100644
--- a/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tidy/readability/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangTidyReadabilityModule
SimplifyBooleanExprCheck.cpp
StaticAccessedThroughInstanceCheck.cpp
StaticDefinitionInAnonymousNamespaceCheck.cpp
+ StringCompareCheck.cpp
UniqueptrDeleteReleaseCheck.cpp
LINK_LIBS
diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tidy/readability/ReadabilityTidyModule.cpp
index 395730dd..f39e4a1e 100644
--- a/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -34,6 +34,7 @@
#include "SimplifyBooleanExprCheck.h"
#include "StaticAccessedThroughInstanceCheck.h"
#include "StaticDefinitionInAnonymousNamespaceCheck.h"
+#include "StringCompareCheck.h"
#include "UniqueptrDeleteReleaseCheck.h"
namespace clang {
@@ -75,6 +76,8 @@ public:
"readability-static-accessed-through-instance");
CheckFactories.registerCheck<StaticDefinitionInAnonymousNamespaceCheck>(
"readability-static-definition-in-anonymous-namespace");
+ CheckFactories.registerCheck<StringCompareCheck>(
+ "readability-string-compare");
CheckFactories.registerCheck<readability::NamedParameterCheck>(
"readability-named-parameter");
CheckFactories.registerCheck<NonConstParameterCheck>(
diff --git a/clang-tidy/readability/StringCompareCheck.cpp b/clang-tidy/readability/StringCompareCheck.cpp
new file mode 100644
index 00000000..e75e80bb
--- /dev/null
+++ b/clang-tidy/readability/StringCompareCheck.cpp
@@ -0,0 +1,82 @@
+//===--- MiscStringCompare.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 "StringCompareCheck.h"
+#include "../utils/FixItHintUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+static const StringRef CompareMessage = "do not use 'compare' to test equality "
+ "of strings; use the string equality "
+ "operator instead";
+
+void StringCompareCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ const auto StrCompare = cxxMemberCallExpr(
+ callee(cxxMethodDecl(hasName("compare"),
+ ofClass(classTemplateSpecializationDecl(
+ hasName("::std::basic_string"))))),
+ hasArgument(0, expr().bind("str2")), argumentCountIs(1),
+ callee(memberExpr().bind("str1")));
+
+ // First and second case: cast str.compare(str) to boolean.
+ Finder->addMatcher(implicitCastExpr(hasImplicitDestinationType(booleanType()),
+ has(StrCompare))
+ .bind("match1"),
+ this);
+
+ // Third and fourth case: str.compare(str) == 0 and str.compare(str) != 0.
+ Finder->addMatcher(
+ binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("!=")),
+ hasEitherOperand(StrCompare.bind("compare")),
+ hasEitherOperand(integerLiteral(equals(0)).bind("zero")))
+ .bind("match2"),
+ this);
+}
+
+void StringCompareCheck::check(const MatchFinder::MatchResult &Result) {
+ if (const auto *Matched = Result.Nodes.getNodeAs<Stmt>("match1")) {
+ diag(Matched->getLocStart(), CompareMessage);
+ return;
+ }
+
+ if (const auto *Matched = Result.Nodes.getNodeAs<Stmt>("match2")) {
+ const ASTContext &Ctx = *Result.Context;
+
+ if (const auto *Zero = Result.Nodes.getNodeAs<Stmt>("zero")) {
+ const auto *Str1 = Result.Nodes.getNodeAs<MemberExpr>("str1");
+ const auto *Str2 = Result.Nodes.getNodeAs<Stmt>("str2");
+ const auto *Compare = Result.Nodes.getNodeAs<Stmt>("compare");
+
+ auto Diag = diag(Matched->getLocStart(), CompareMessage);
+
+ if (Str1->isArrow())
+ Diag << FixItHint::CreateInsertion(Str1->getLocStart(), "*");
+
+ Diag << tooling::fixit::createReplacement(*Zero, *Str2, Ctx)
+ << tooling::fixit::createReplacement(*Compare, *Str1->getBase(),
+ Ctx);
+ }
+ }
+
+ // FIXME: Add fixit to fix the code for case one and two (match1).
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tidy/readability/StringCompareCheck.h b/clang-tidy/readability/StringCompareCheck.h
new file mode 100644
index 00000000..248d2ee8
--- /dev/null
+++ b/clang-tidy/readability/StringCompareCheck.h
@@ -0,0 +1,36 @@
+//===--- StringCompareCheck.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_READABILITY_STRINGCOMPARECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRINGCOMPARECHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// This check flags all calls compare when used to check for string
+/// equality or inequality.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-string-compare.html
+class StringCompareCheck : public ClangTidyCheck {
+public:
+ StringCompareCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRINGCOMPARECHECK_H