Using an early return as it is more clear; NFC.

llvm-svn: 246447
This commit is contained in:
Aaron Ballman 2015-08-31 15:28:57 +00:00
parent 54f3657448
commit bf89109013
9 changed files with 156 additions and 148 deletions

View File

@ -21,25 +21,26 @@ namespace misc {
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.
if (getLangOpts().CPlusPlus) {
const auto CheckForEndCall = hasArgument(
1, anyOf(constructExpr(
has(memberCallExpr(callee(methodDecl(hasName("end"))))
.bind("InaccEndCall"))),
anything()));
if (!getLangOpts().CPlusPlus)
return;
Finder->addMatcher(
memberCallExpr(
on(hasType(namedDecl(matchesName("^::std::")))),
callee(methodDecl(hasName("erase"))), argumentCountIs(1),
hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
"^::std::(remove(_if)?|unique)$"))),
CheckForEndCall)
.bind("InaccAlgCall"))),
unless(isInTemplateInstantiation()))
.bind("InaccErase"),
this);
}
const auto CheckForEndCall = hasArgument(
1,
anyOf(constructExpr(has(memberCallExpr(callee(methodDecl(hasName("end"))))
.bind("InaccEndCall"))),
anything()));
Finder->addMatcher(
memberCallExpr(
on(hasType(namedDecl(matchesName("^::std::")))),
callee(methodDecl(hasName("erase"))), argumentCountIs(1),
hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
"^::std::(remove(_if)?|unique)$"))),
CheckForEndCall)
.bind("InaccAlgCall"))),
unless(isInTemplateInstantiation()))
.bind("InaccErase"),
this);
}
void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -30,33 +30,34 @@ static bool areTypesCompatible(QualType Left, QualType Right) {
void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus) {
const std::string Algorithms =
"^::std::(find|count|equal_range|lower_bound|upper_bound)$";
const auto ContainerMatcher = classTemplateSpecializationDecl(
matchesName("^::std::(unordered_)?(multi)?(set|map)$"));
const auto Matcher =
callExpr(
callee(functionDecl(matchesName(Algorithms))),
hasArgument(
0, constructExpr(has(memberCallExpr(
callee(methodDecl(hasName("begin"))),
on(declRefExpr(
hasDeclaration(decl().bind("IneffContObj")),
anyOf(hasType(ContainerMatcher.bind("IneffCont")),
hasType(pointsTo(ContainerMatcher.bind(
"IneffContPtr")))))
.bind("IneffContExpr")))))),
hasArgument(1, constructExpr(has(memberCallExpr(
callee(methodDecl(hasName("end"))),
on(declRefExpr(hasDeclaration(
equalsBoundNode("IneffContObj")))))))),
hasArgument(2, expr().bind("AlgParam")),
unless(isInTemplateInstantiation()))
.bind("IneffAlg");
if (!getLangOpts().CPlusPlus)
return;
Finder->addMatcher(Matcher, this);
}
const std::string Algorithms =
"^::std::(find|count|equal_range|lower_bound|upper_bound)$";
const auto ContainerMatcher = classTemplateSpecializationDecl(
matchesName("^::std::(unordered_)?(multi)?(set|map)$"));
const auto Matcher =
callExpr(
callee(functionDecl(matchesName(Algorithms))),
hasArgument(
0, constructExpr(has(memberCallExpr(
callee(methodDecl(hasName("begin"))),
on(declRefExpr(
hasDeclaration(decl().bind("IneffContObj")),
anyOf(hasType(ContainerMatcher.bind("IneffCont")),
hasType(pointsTo(
ContainerMatcher.bind("IneffContPtr")))))
.bind("IneffContExpr")))))),
hasArgument(1, constructExpr(has(memberCallExpr(
callee(methodDecl(hasName("end"))),
on(declRefExpr(hasDeclaration(
equalsBoundNode("IneffContObj")))))))),
hasArgument(2, expr().bind("AlgParam")),
unless(isInTemplateInstantiation()))
.bind("IneffAlg");
Finder->addMatcher(Matcher, this);
}
void InefficientAlgorithmCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -19,17 +19,18 @@ namespace tidy {
void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++11; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus11) {
Finder->addMatcher(
constructorDecl(unless(isImplicit()), allOf(
isMoveConstructor(),
hasAnyConstructorInitializer(
ctorInitializer(withInitializer(constructExpr(hasDeclaration(
constructorDecl(isCopyConstructor()).bind("ctor")
)))).bind("init")
)
)), this);
}
if (!getLangOpts().CPlusPlus11)
return;
Finder->addMatcher(
constructorDecl(unless(isImplicit()), allOf(
isMoveConstructor(),
hasAnyConstructorInitializer(
ctorInitializer(withInitializer(constructExpr(hasDeclaration(
constructorDecl(isCopyConstructor()).bind("ctor")
)))).bind("init")
)
)), this);
}
void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -19,13 +19,14 @@ namespace tidy {
void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++11; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus11) {
Finder->addMatcher(
methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")),
unless(isImplicit()), unless(isDeleted()))
.bind("decl"),
this);
}
if (!getLangOpts().CPlusPlus11)
return;
Finder->addMatcher(
methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")),
unless(isImplicit()), unless(isDeleted()))
.bind("decl"),
this);
}
void NoexceptMoveConstructorCheck::check(

View File

@ -30,44 +30,44 @@ void StaticAssertCheck::registerMatchers(MatchFinder *Finder) {
// FIXME: I don't see why this checker couldn't also be interesting for
// _Static_assert in C11, or static_assert if <assert.h> has been included,
// but it is currently only enabled for C++11. Investigate.
if (getLangOpts().CPlusPlus11) {
auto IsAlwaysFalse = expr(ignoringParenImpCasts(
expr(anyOf(boolLiteral(equals(false)), integerLiteral(equals(0)),
nullPtrLiteralExpr(), gnuNullExpr()))
.bind("isAlwaysFalse")));
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(
IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr")));
auto AssertExprRoot =
anyOf(binaryOperator(
anyOf(hasOperatorName("&&"), hasOperatorName("==")),
hasEitherOperand(
ignoringImpCasts(stringLiteral().bind("assertMSG"))),
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
anything()))
.bind("assertExprRoot"),
IsAlwaysFalse);
auto NonConstexprFunctionCall =
callExpr(hasDeclaration(functionDecl(unless(isConstexpr()))));
auto AssertCondition =
expr(anyOf(expr(ignoringParenCasts(
anyOf(AssertExprRoot,
unaryOperator(hasUnaryOperand(
ignoringParenCasts(AssertExprRoot)))))),
anything()),
unless(findAll(NonConstexprFunctionCall)))
.bind("condition");
auto Condition =
anyOf(ignoringParenImpCasts(callExpr(
hasDeclaration(functionDecl(hasName("__builtin_expect"))),
hasArgument(0, AssertCondition))),
AssertCondition);
if (!getLangOpts().CPlusPlus11)
return;
Finder->addMatcher(stmt(anyOf(conditionalOperator(hasCondition(Condition)),
ifStmt(hasCondition(Condition))),
unless(isInTemplateInstantiation()))
.bind("condStmt"),
this);
}
auto IsAlwaysFalse = expr(ignoringParenImpCasts(
expr(anyOf(boolLiteral(equals(false)), integerLiteral(equals(0)),
nullPtrLiteralExpr(), gnuNullExpr()))
.bind("isAlwaysFalse")));
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(
IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr")));
auto AssertExprRoot = anyOf(
binaryOperator(
anyOf(hasOperatorName("&&"), hasOperatorName("==")),
hasEitherOperand(ignoringImpCasts(stringLiteral().bind("assertMSG"))),
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
anything()))
.bind("assertExprRoot"),
IsAlwaysFalse);
auto NonConstexprFunctionCall =
callExpr(hasDeclaration(functionDecl(unless(isConstexpr()))));
auto AssertCondition =
expr(
anyOf(expr(ignoringParenCasts(anyOf(
AssertExprRoot, unaryOperator(hasUnaryOperand(
ignoringParenCasts(AssertExprRoot)))))),
anything()),
unless(findAll(NonConstexprFunctionCall)))
.bind("condition");
auto Condition =
anyOf(ignoringParenImpCasts(callExpr(
hasDeclaration(functionDecl(hasName("__builtin_expect"))),
hasArgument(0, AssertCondition))),
AssertCondition);
Finder->addMatcher(stmt(anyOf(conditionalOperator(hasCondition(Condition)),
ifStmt(hasCondition(Condition))),
unless(isInTemplateInstantiation()))
.bind("condStmt"),
this);
}
void StaticAssertCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -58,17 +58,18 @@ void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
//
// Only register the matchers for C++11; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus11) {
Finder->addMatcher(
compoundStmt(
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))),
forEach(ignoringTemporaryExpr(
constructExpr(hasDeclaration(constructorDecl(ofClass(
recordDecl(baseOfBoundNode("parent"))))))
.bind("construct"))),
unless(isInTemplateInstantiation())),
this);
}
if (!getLangOpts().CPlusPlus11)
return;
Finder->addMatcher(
compoundStmt(
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))),
forEach(ignoringTemporaryExpr(
constructExpr(hasDeclaration(constructorDecl(ofClass(
recordDecl(baseOfBoundNode("parent"))))))
.bind("construct"))),
unless(isInTemplateInstantiation())),
this);
}
void UndelegatedConstructorCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -20,23 +20,24 @@ namespace misc {
void UniqueptrResetReleaseCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++11; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus11) {
Finder->addMatcher(
memberCallExpr(
on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
callee(methodDecl(hasName("reset"),
ofClass(recordDecl(hasName("::std::unique_ptr"),
decl().bind("left_class"))))),
has(memberCallExpr(
on(expr().bind("right")),
callee(memberExpr().bind("release_member")),
callee(methodDecl(
hasName("release"),
ofClass(recordDecl(hasName("::std::unique_ptr"),
decl().bind("right_class"))))))))
.bind("reset_call"),
this);
}
if (!getLangOpts().CPlusPlus11)
return;
Finder->addMatcher(
memberCallExpr(
on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
callee(methodDecl(hasName("reset"),
ofClass(recordDecl(hasName("::std::unique_ptr"),
decl().bind("left_class"))))),
has(memberCallExpr(
on(expr().bind("right")),
callee(memberExpr().bind("release_member")),
callee(methodDecl(
hasName("release"),
ofClass(recordDecl(hasName("::std::unique_ptr"),
decl().bind("right_class"))))))))
.bind("reset_call"),
this);
}
namespace {

View File

@ -20,13 +20,14 @@ namespace tidy {
void UnusedAliasDeclsCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++11; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus11) {
// We cannot do anything about headers (yet), as the alias declarations
// used in one header could be used by some other translation unit.
Finder->addMatcher(
namespaceAliasDecl(isExpansionInMainFile()).bind("alias"), this);
Finder->addMatcher(nestedNameSpecifier().bind("nns"), this);
}
if (!getLangOpts().CPlusPlus11)
return;
// We cannot do anything about headers (yet), as the alias declarations
// used in one header could be used by some other translation unit.
Finder->addMatcher(namespaceAliasDecl(isExpansionInMainFile()).bind("alias"),
this);
Finder->addMatcher(nestedNameSpecifier().bind("nns"), this);
}
void UnusedAliasDeclsCheck::check(const MatchFinder::MatchResult &Result) {

View File

@ -27,20 +27,21 @@ namespace misc {
void UnusedRAIICheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++; the functionality currently does not
// provide any benefit to other languages, despite being benign.
if (getLangOpts().CPlusPlus) {
// Look for temporaries that are constructed in-place and immediately
// destroyed. Look for temporaries created by a functional cast but not for
// those returned from a call.
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp");
Finder->addMatcher(
exprWithCleanups(
unless(isInTemplateInstantiation()),
hasParent(compoundStmt().bind("compound")),
hasType(recordDecl(hasNonTrivialDestructor())),
anyOf(has(BindTemp), has(functionalCastExpr(has(BindTemp)))))
.bind("expr"),
this);
}
if (!getLangOpts().CPlusPlus)
return;
// Look for temporaries that are constructed in-place and immediately
// destroyed. Look for temporaries created by a functional cast but not for
// those returned from a call.
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp");
Finder->addMatcher(
exprWithCleanups(
unless(isInTemplateInstantiation()),
hasParent(compoundStmt().bind("compound")),
hasType(recordDecl(hasNonTrivialDestructor())),
anyOf(has(BindTemp), has(functionalCastExpr(has(BindTemp)))))
.bind("expr"),
this);
}
void UnusedRAIICheck::check(const MatchFinder::MatchResult &Result) {