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
This commit is contained in:
parent
a354c5c433
commit
1612fa07d3
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -14,6 +14,7 @@ add_clang_library(clangTidyReadabilityModule
|
|||
RedundantControlFlowCheck.cpp
|
||||
RedundantStringCStrCheck.cpp
|
||||
RedundantSmartptrGetCheck.cpp
|
||||
RedundantStringInitCheck.cpp
|
||||
SimplifyBooleanExprCheck.cpp
|
||||
UniqueptrDeleteReleaseCheck.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>(
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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("");
|
||||
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue