diff options
author | Alexander Kornienko <alexfh@google.com> | 2018-01-30 14:55:50 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2018-01-30 14:55:50 +0000 |
commit | 13f62172d70a89a2f7c9c68c45aab7c7fe62b6e2 (patch) | |
tree | c20c72ce9905f743145625af5d261dd85c7900bd /clang-tidy/readability | |
parent | 8a3a9295153fdf95f16415c8d7742f07feec8dde (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.txt | 1 | ||||
-rw-r--r-- | clang-tidy/readability/ReadabilityTidyModule.cpp | 3 | ||||
-rw-r--r-- | clang-tidy/readability/StringCompareCheck.cpp | 82 | ||||
-rw-r--r-- | clang-tidy/readability/StringCompareCheck.h | 36 |
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 |