diff options
author | Alexander Kornienko <alexfh@google.com> | 2016-02-25 23:57:23 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2016-02-25 23:57:23 +0000 |
commit | 1612fa07d351cf5b4a4595dba07e12416a957137 (patch) | |
tree | 81a3dba89d7b55dfdff701c84ff80e4cd05b670e | |
parent | a354c5c43324127b44d2b7e2e2dccf07692b1013 (diff) | |
download | bcm5719-llvm-1612fa07d351cf5b4a4595dba07e12416a957137.tar.gz bcm5719-llvm-1612fa07d351cf5b4a4595dba07e12416a957137.zip |
Add a new check, readability-redundant-string-init, that checks unnecessary string initializations.
Reviewers: hokein, alexfh
Subscribers: cfe-commits
Patch by Shuai Wang!
Differential Revision: http://reviews.llvm.org/D17586
llvm-svn: 261939
9 files changed, 204 insertions, 4 deletions
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 0cb44f9d1df..d1cb4eb2d9e 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -338,10 +338,9 @@ void ClangTidyDiagnosticConsumer::HandleDiagnostic( Errors.push_back(ClangTidyError(CheckName, Level, IsWarningAsError)); } - // FIXME: Provide correct LangOptions for each file. - LangOptions LangOpts; ClangTidyDiagnosticRenderer Converter( - LangOpts, &Context.DiagEngine->getDiagnosticOptions(), Errors.back()); + Context.getLangOpts(), &Context.DiagEngine->getDiagnosticOptions(), + Errors.back()); SmallString<100> Message; Info.FormatDiagnostic(Message); SourceManager *Sources = nullptr; diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index 420f8f48af2..cbd376c627f 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -151,7 +151,7 @@ public: void setASTContext(ASTContext *Context); /// \brief Gets the language options from the AST context. - LangOptions getLangOpts() const { return LangOpts; } + const LangOptions &getLangOpts() const { return LangOpts; } /// \brief Returns the name of the clang-tidy check which produced this /// diagnostic ID. diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 88df0588530..bb56917a388 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -14,6 +14,7 @@ add_clang_library(clangTidyReadabilityModule RedundantControlFlowCheck.cpp RedundantStringCStrCheck.cpp RedundantSmartptrGetCheck.cpp + RedundantStringInitCheck.cpp SimplifyBooleanExprCheck.cpp UniqueptrDeleteReleaseCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index d2fb21703b0..5803f5f0997 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -21,6 +21,7 @@ #include "RedundantControlFlowCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" +#include "RedundantStringInitCheck.h" #include "SimplifyBooleanExprCheck.h" #include "UniqueptrDeleteReleaseCheck.h" @@ -53,6 +54,8 @@ public: "readability-redundant-smartptr-get"); CheckFactories.registerCheck<RedundantStringCStrCheck>( "readability-redundant-string-cstr"); + CheckFactories.registerCheck<RedundantStringInitCheck>( + "readability-redundant-string-init"); CheckFactories.registerCheck<SimplifyBooleanExprCheck>( "readability-simplify-boolean-expr"); CheckFactories.registerCheck<UniqueptrDeleteReleaseCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp new file mode 100644 index 00000000000..ad6c2cdd416 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -0,0 +1,62 @@ +//===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RedundantStringInitCheck.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +namespace { + +AST_MATCHER(StringLiteral, lengthIsZero) { return Node.getLength() == 0; } + +} // namespace + +void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) { + if (!getLangOpts().CPlusPlus) + return; + + const auto StringCtorExpr = cxxConstructExpr( + hasDeclaration(cxxMethodDecl(hasName("basic_string"))), + argumentCountIs(2), + hasArgument(0, ignoringParenImpCasts(stringLiteral(lengthIsZero()))), + hasArgument(1, cxxDefaultArgExpr())); + + // string foo = ""; + // OR + // string bar(""); + Finder->addMatcher( + namedDecl(varDecl(hasType(cxxRecordDecl(hasName("basic_string"))), + hasInitializer( + expr(anyOf(StringCtorExpr, + exprWithCleanups(has(expr(anyOf( + StringCtorExpr, + cxxConstructExpr(hasArgument( + 0, cxxBindTemporaryExpr(has( + StringCtorExpr)))))))))) + .bind("expr")))) + .bind("decl"), + this); +} + +void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) { + const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr"); + const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl"); + diag(CtorExpr->getExprLoc(), "redundant string initialization") + << FixItHint::CreateReplacement(CtorExpr->getSourceRange(), + Decl->getName()); +} + +} // namespace readability +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h new file mode 100644 index 00000000000..0a32eb6defc --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.h @@ -0,0 +1,32 @@ +//===- RedundantStringInitCheck.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_REDUNDANT_STRING_INIT_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_STRING_INIT_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace readability { + +/// Finds unnecessary string initializations. +class RedundantStringInitCheck : public ClangTidyCheck { +public: + RedundantStringInitCheck(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_REDUNDANT_STRING_INIT_H diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 6b06e92b0a6..9b3e7d3bcaf 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -99,5 +99,6 @@ Clang-Tidy Checks readability-redundant-control-flow readability-redundant-smartptr-get readability-redundant-string-cstr + readability-redundant-string-init readability-simplify-boolean-expr readability-uniqueptr-delete-release diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-redundant-string-init.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-redundant-string-init.rst new file mode 100644 index 00000000000..71cb1455d6b --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-redundant-string-init.rst @@ -0,0 +1,16 @@ +.. title:: clang-tidy - readability-redundant-string-init + +readability-redundant-string-init +================================= + + +Finds unnecessary string initializations. + +Examples: + +.. code:: c++ + + // Initializing string with empty string literal is unnecessary. + std::string a = ""; + std::string b(""); + diff --git a/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp b/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp new file mode 100644 index 00000000000..ec5af367e97 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-redundant-string-init.cpp @@ -0,0 +1,86 @@ +// RUN: %check_clang_tidy %s readability-redundant-string-init %t + +namespace std { +template <typename T> +class allocator {}; +template <typename T> +class char_traits {}; +template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>> +struct basic_string { + basic_string(); + basic_string(const basic_string&); + basic_string(const C *, const A &a = A()); + ~basic_string(); +}; +typedef basic_string<char> string; +typedef basic_string<wchar_t> wstring; +} + +void f() { + std::string a = ""; + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init] + // CHECK-FIXES: std::string a; + std::string b(""); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization + // CHECK-FIXES: std::string b; + std::string c = R"()"; + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization + // CHECK-FIXES: std::string c; + std::string d(R"()"); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization + // CHECK-FIXES: std::string d; + + std::string u = "u"; + std::string w("w"); + std::string x = R"(x)"; + std::string y(R"(y)"); + std::string z; +} + +void g() { + std::wstring a = L""; + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization + // CHECK-FIXES: std::wstring a; + std::wstring b(L""); + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization + // CHECK-FIXES: std::wstring b; + std::wstring c = LR"()"; + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization + // CHECK-FIXES: std::wstring c; + std::wstring d(LR"()"); + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization + // CHECK-FIXES: std::wstring d; + + std::wstring u = L"u"; + std::wstring w(L"w"); + std::wstring x = LR"(x)"; + std::wstring y(LR"(y)"); + std::wstring z; +} + +template <typename T> +void templ() { + std::string s = ""; + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization + // CHECK-FIXES: std::string s; +} + +#define M(x) x +#define N { std::string s = ""; } +// CHECK-FIXES: #define N { std::string s = ""; } + +void h() { + templ<int>(); + templ<double>(); + + M({ std::string s = ""; }) + // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization + // CHECK-FIXES: M({ std::string s; }) + + N + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization + // CHECK-FIXES: N + N + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization + // CHECK-FIXES: N +} |