[clang-tidy] misc-inaccurate-erase: support call by pointer

+ replace matchesName calls with more efficient alternatives.

llvm-svn: 304811
This commit is contained in:
Alexander Kornienko 2017-06-06 17:49:45 +00:00
parent ad7a1805be
commit 0bdd8a1964
2 changed files with 14 additions and 3 deletions

View File

@ -18,6 +18,10 @@ namespace clang {
namespace tidy {
namespace misc {
namespace {
AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
}
void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++; the functionality currently does not
// provide any benefit to other languages, despite being benign.
@ -30,13 +34,14 @@ void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
.bind("InaccEndCall")))),
anything()));
const auto DeclInStd = decl(isInStdNamespace());
Finder->addMatcher(
cxxMemberCallExpr(
on(hasType(namedDecl(matchesName("^::std::")))),
on(anyOf(hasType(DeclInStd), hasType(pointsTo(DeclInStd)))),
callee(cxxMethodDecl(hasName("erase"))), argumentCountIs(1),
hasArgument(0, has(ignoringParenImpCasts(
callExpr(callee(functionDecl(matchesName(
"^::std::(remove(_if)?|unique)$"))),
callExpr(callee(functionDecl(hasAnyName(
"remove", "remove_if", "unique"))),
CheckForEndCall)
.bind("InaccAlgCall")))),
unless(isInTemplateInstantiation()))

View File

@ -56,6 +56,12 @@ int main() {
// CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}}
v.erase(remove(v.begin(), v.end(), 20), v.end());
auto *p = &v;
p->erase(remove(p->begin(), p->end(), 11));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one
// CHECK-FIXES: {{^ }}p->erase(remove(p->begin(), p->end(), 11), p->end());{{$}}
// Fix is not trivial.
auto it = v.end();
v.erase(remove(v.begin(), it, 10));