mirror of
https://github.com/intel/llvm.git
synced 2026-02-07 07:39:11 +08:00
A bit of AST matcher cleanup, NFC.
Removed the uses of the allOf() matcher inside node matchers that are implicit allOf(). Replaced uses of allOf() with the explicit node matcher where it makes matchers more readable. Replace anyOf(hasName(), hasName(), ...) with the more efficient and readable hasAnyName(). llvm-svn: 347520
This commit is contained in:
@@ -450,8 +450,8 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||
typeLoc(IsInMovedNs,
|
||||
loc(qualType(hasDeclaration(DeclMatcher.bind("from_decl")))),
|
||||
unless(anyOf(hasParent(typeLoc(loc(qualType(
|
||||
allOf(hasDeclaration(DeclMatcher),
|
||||
unless(templateSpecializationType())))))),
|
||||
hasDeclaration(DeclMatcher),
|
||||
unless(templateSpecializationType()))))),
|
||||
hasParent(nestedNameSpecifierLoc()),
|
||||
hasAncestor(isImplicit()),
|
||||
hasAncestor(UsingShadowDeclInClass),
|
||||
@@ -505,13 +505,12 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||
hasAncestor(namespaceDecl(isAnonymous())),
|
||||
hasAncestor(cxxRecordDecl()))),
|
||||
hasParent(namespaceDecl()));
|
||||
Finder->addMatcher(
|
||||
expr(allOf(hasAncestor(decl().bind("dc")), IsInMovedNs,
|
||||
unless(hasAncestor(isImplicit())),
|
||||
anyOf(callExpr(callee(FuncMatcher)).bind("call"),
|
||||
declRefExpr(to(FuncMatcher.bind("func_decl")))
|
||||
.bind("func_ref")))),
|
||||
this);
|
||||
Finder->addMatcher(expr(hasAncestor(decl().bind("dc")), IsInMovedNs,
|
||||
unless(hasAncestor(isImplicit())),
|
||||
anyOf(callExpr(callee(FuncMatcher)).bind("call"),
|
||||
declRefExpr(to(FuncMatcher.bind("func_decl")))
|
||||
.bind("func_ref"))),
|
||||
this);
|
||||
|
||||
auto GlobalVarMatcher = varDecl(
|
||||
hasGlobalStorage(), hasParent(namespaceDecl()),
|
||||
|
||||
@@ -20,11 +20,11 @@ void BoolPointerImplicitConversionCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// condition. Filter negations.
|
||||
Finder->addMatcher(
|
||||
ifStmt(hasCondition(findAll(implicitCastExpr(
|
||||
allOf(unless(hasParent(unaryOperator(hasOperatorName("!")))),
|
||||
hasSourceExpression(expr(
|
||||
hasType(pointerType(pointee(booleanType()))),
|
||||
ignoringParenImpCasts(declRefExpr().bind("expr")))),
|
||||
hasCastKind(CK_PointerToBoolean))))),
|
||||
unless(hasParent(unaryOperator(hasOperatorName("!")))),
|
||||
hasSourceExpression(
|
||||
expr(hasType(pointerType(pointee(booleanType()))),
|
||||
ignoringParenImpCasts(declRefExpr().bind("expr")))),
|
||||
hasCastKind(CK_PointerToBoolean)))),
|
||||
unless(isInTemplateInstantiation()))
|
||||
.bind("if"),
|
||||
this);
|
||||
|
||||
@@ -190,12 +190,12 @@ void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) {
|
||||
return;
|
||||
|
||||
Finder->addMatcher(
|
||||
functionDecl(allOf(anyOf(isNoThrow(), cxxDestructorDecl(),
|
||||
cxxConstructorDecl(isMoveConstructor()),
|
||||
cxxMethodDecl(isMoveAssignmentOperator()),
|
||||
hasName("main"), hasName("swap"),
|
||||
isEnabled(FunctionsThatShouldNotThrow)),
|
||||
throws(unless(isIgnored(IgnoredExceptions)))))
|
||||
functionDecl(anyOf(isNoThrow(), cxxDestructorDecl(),
|
||||
cxxConstructorDecl(isMoveConstructor()),
|
||||
cxxMethodDecl(isMoveAssignmentOperator()),
|
||||
hasName("main"), hasName("swap"),
|
||||
isEnabled(FunctionsThatShouldNotThrow)),
|
||||
throws(unless(isIgnored(IgnoredExceptions))))
|
||||
.bind("thrower"),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -29,17 +29,17 @@ void MisplacedOperatorInStrlenInAllocCheck::registerMatchers(
|
||||
const auto BadUse =
|
||||
callExpr(callee(StrLenFunc),
|
||||
hasAnyArgument(ignoringImpCasts(
|
||||
binaryOperator(allOf(hasOperatorName("+"),
|
||||
hasRHS(ignoringParenImpCasts(
|
||||
integerLiteral(equals(1))))))
|
||||
binaryOperator(
|
||||
hasOperatorName("+"),
|
||||
hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))
|
||||
.bind("BinOp"))))
|
||||
.bind("StrLen");
|
||||
|
||||
const auto BadArg = anyOf(
|
||||
allOf(hasDescendant(BadUse),
|
||||
unless(binaryOperator(allOf(
|
||||
allOf(unless(binaryOperator(
|
||||
hasOperatorName("+"), hasLHS(BadUse),
|
||||
hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))))),
|
||||
hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))),
|
||||
hasDescendant(BadUse)),
|
||||
BadUse);
|
||||
|
||||
const auto Alloc0Func =
|
||||
|
||||
@@ -119,30 +119,30 @@ void SuspiciousEnumUsageCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||
|
||||
void SuspiciousEnumUsageCheck::registerMatchers(MatchFinder *Finder) {
|
||||
const auto enumExpr = [](StringRef RefName, StringRef DeclName) {
|
||||
return allOf(ignoringImpCasts(expr().bind(RefName)),
|
||||
ignoringImpCasts(hasType(enumDecl().bind(DeclName))));
|
||||
return expr(ignoringImpCasts(expr().bind(RefName)),
|
||||
ignoringImpCasts(hasType(enumDecl().bind(DeclName))));
|
||||
};
|
||||
|
||||
Finder->addMatcher(
|
||||
binaryOperator(hasOperatorName("|"), hasLHS(enumExpr("", "enumDecl")),
|
||||
hasRHS(allOf(enumExpr("", "otherEnumDecl"),
|
||||
ignoringImpCasts(hasType(enumDecl(
|
||||
unless(equalsBoundNode("enumDecl"))))))))
|
||||
hasRHS(expr(enumExpr("", "otherEnumDecl"),
|
||||
ignoringImpCasts(hasType(enumDecl(
|
||||
unless(equalsBoundNode("enumDecl"))))))))
|
||||
.bind("diffEnumOp"),
|
||||
this);
|
||||
|
||||
Finder->addMatcher(
|
||||
binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("|")),
|
||||
hasLHS(enumExpr("lhsExpr", "enumDecl")),
|
||||
hasRHS(allOf(enumExpr("rhsExpr", ""),
|
||||
ignoringImpCasts(hasType(enumDecl(
|
||||
equalsBoundNode("enumDecl"))))))),
|
||||
hasRHS(expr(enumExpr("rhsExpr", ""),
|
||||
ignoringImpCasts(hasType(
|
||||
enumDecl(equalsBoundNode("enumDecl"))))))),
|
||||
this);
|
||||
|
||||
Finder->addMatcher(
|
||||
binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("|")),
|
||||
hasEitherOperand(
|
||||
allOf(hasType(isInteger()), unless(enumExpr("", "")))),
|
||||
expr(hasType(isInteger()), unless(enumExpr("", "")))),
|
||||
hasEitherOperand(enumExpr("enumExpr", "enumDecl"))),
|
||||
this);
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ void UseAfterMoveFinder::getReinits(
|
||||
declStmt(hasDescendant(equalsNode(MovedVariable))),
|
||||
// clear() and assign() on standard containers.
|
||||
cxxMemberCallExpr(
|
||||
on(allOf(DeclRefMatcher, StandardContainerTypeMatcher)),
|
||||
on(expr(DeclRefMatcher, StandardContainerTypeMatcher)),
|
||||
// To keep the matcher simple, we check for assign() calls
|
||||
// on all standard containers, even though only vector,
|
||||
// deque, forward_list and list have assign(). If assign()
|
||||
@@ -307,7 +307,7 @@ void UseAfterMoveFinder::getReinits(
|
||||
callee(cxxMethodDecl(hasAnyName("clear", "assign")))),
|
||||
// reset() on standard smart pointers.
|
||||
cxxMemberCallExpr(
|
||||
on(allOf(DeclRefMatcher, StandardSmartPointerTypeMatcher)),
|
||||
on(expr(DeclRefMatcher, StandardSmartPointerTypeMatcher)),
|
||||
callee(cxxMethodDecl(hasName("reset")))),
|
||||
// Methods that have the [[clang::reinitializes]] attribute.
|
||||
cxxMemberCallExpr(
|
||||
|
||||
@@ -18,18 +18,18 @@ namespace tidy {
|
||||
namespace cppcoreguidelines {
|
||||
|
||||
void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
|
||||
const auto IsGlobal =
|
||||
allOf(hasGlobalStorage(),
|
||||
hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
|
||||
namespaceDecl(), // Namespace scope.
|
||||
recordDecl())), // Class scope.
|
||||
unless(isConstexpr()));
|
||||
const auto GlobalVarDecl =
|
||||
varDecl(hasGlobalStorage(),
|
||||
hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
|
||||
namespaceDecl(), // Namespace scope.
|
||||
recordDecl())), // Class scope.
|
||||
unless(isConstexpr()));
|
||||
|
||||
const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
|
||||
varDecl(IsGlobal, unless(isDefinition())).bind("referencee")));
|
||||
varDecl(GlobalVarDecl, unless(isDefinition())).bind("referencee")));
|
||||
|
||||
Finder->addMatcher(
|
||||
varDecl(IsGlobal, isDefinition(),
|
||||
varDecl(GlobalVarDecl, isDefinition(),
|
||||
hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
|
||||
.bind("var"),
|
||||
this);
|
||||
|
||||
@@ -87,36 +87,34 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// resources. This check assumes that all pointer arguments of a legacy
|
||||
// functions shall be 'gsl::owner<>'.
|
||||
Finder->addMatcher(
|
||||
callExpr(
|
||||
allOf(callee(LegacyOwnerConsumers),
|
||||
hasAnyArgument(allOf(unless(ignoringImpCasts(ConsideredOwner)),
|
||||
hasType(pointerType())))))
|
||||
callExpr(callee(LegacyOwnerConsumers),
|
||||
hasAnyArgument(expr(unless(ignoringImpCasts(ConsideredOwner)),
|
||||
hasType(pointerType()))))
|
||||
.bind("legacy_consumer"),
|
||||
this);
|
||||
|
||||
// Matching assignment to owners, with the rhs not being an owner nor creating
|
||||
// one.
|
||||
Finder->addMatcher(binaryOperator(allOf(matchers::isAssignmentOperator(),
|
||||
hasLHS(IsOwnerType),
|
||||
hasRHS(unless(ConsideredOwner))))
|
||||
Finder->addMatcher(binaryOperator(matchers::isAssignmentOperator(),
|
||||
hasLHS(IsOwnerType),
|
||||
hasRHS(unless(ConsideredOwner)))
|
||||
.bind("owner_assignment"),
|
||||
this);
|
||||
|
||||
// Matching initialization of owners with non-owners, nor creating owners.
|
||||
Finder->addMatcher(
|
||||
namedDecl(
|
||||
varDecl(allOf(hasInitializer(unless(ConsideredOwner)), IsOwnerType))
|
||||
.bind("owner_initialization")),
|
||||
namedDecl(varDecl(hasInitializer(unless(ConsideredOwner)), IsOwnerType)
|
||||
.bind("owner_initialization")),
|
||||
this);
|
||||
|
||||
const auto HasConstructorInitializerForOwner =
|
||||
has(cxxConstructorDecl(forEachConstructorInitializer(
|
||||
cxxCtorInitializer(allOf(isMemberInitializer(), forField(IsOwnerType),
|
||||
withInitializer(
|
||||
// Avoid templatesdeclaration with
|
||||
// excluding parenListExpr.
|
||||
allOf(unless(ConsideredOwner),
|
||||
unless(parenListExpr())))))
|
||||
cxxCtorInitializer(
|
||||
isMemberInitializer(), forField(IsOwnerType),
|
||||
withInitializer(
|
||||
// Avoid templatesdeclaration with
|
||||
// excluding parenListExpr.
|
||||
allOf(unless(ConsideredOwner), unless(parenListExpr()))))
|
||||
.bind("owner_member_initializer"))));
|
||||
|
||||
// Match class member initialization that expects owners, but does not get
|
||||
@@ -125,11 +123,11 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
// Matching on assignment operations where the RHS is a newly created owner,
|
||||
// but the LHS is not an owner.
|
||||
Finder->addMatcher(
|
||||
binaryOperator(allOf(matchers::isAssignmentOperator(),
|
||||
hasLHS(unless(IsOwnerType)), hasRHS(CreatesOwner)))
|
||||
.bind("bad_owner_creation_assignment"),
|
||||
this);
|
||||
Finder->addMatcher(binaryOperator(matchers::isAssignmentOperator(),
|
||||
hasLHS(unless(IsOwnerType)),
|
||||
hasRHS(CreatesOwner))
|
||||
.bind("bad_owner_creation_assignment"),
|
||||
this);
|
||||
|
||||
// Matching on initialization operations where the initial value is a newly
|
||||
// created owner, but the LHS is not an owner.
|
||||
@@ -160,10 +158,9 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// Matching on functions, that return an owner/resource, but don't declare
|
||||
// their return type as owner.
|
||||
Finder->addMatcher(
|
||||
functionDecl(
|
||||
allOf(hasDescendant(returnStmt(hasReturnValue(ConsideredOwner))
|
||||
.bind("bad_owner_return")),
|
||||
unless(returns(qualType(hasDeclaration(OwnerDecl))))))
|
||||
functionDecl(hasDescendant(returnStmt(hasReturnValue(ConsideredOwner))
|
||||
.bind("bad_owner_return")),
|
||||
unless(returns(qualType(hasDeclaration(OwnerDecl)))))
|
||||
.bind("function_decl"),
|
||||
this);
|
||||
|
||||
@@ -171,10 +168,9 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// destructor to properly release the owner.
|
||||
Finder->addMatcher(
|
||||
cxxRecordDecl(
|
||||
allOf(
|
||||
has(fieldDecl(IsOwnerType).bind("undestructed_owner_member")),
|
||||
anyOf(unless(has(cxxDestructorDecl())),
|
||||
has(cxxDestructorDecl(anyOf(isDefaulted(), isDeleted()))))))
|
||||
has(fieldDecl(IsOwnerType).bind("undestructed_owner_member")),
|
||||
anyOf(unless(has(cxxDestructorDecl())),
|
||||
has(cxxDestructorDecl(anyOf(isDefaulted(), isDeleted())))))
|
||||
.bind("non_destructor_class"),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -34,18 +34,17 @@ void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
if (!getLangOpts().CPlusPlus11)
|
||||
return;
|
||||
|
||||
Finder->addMatcher(
|
||||
varDecl(allOf(
|
||||
// Match global, statically stored objects...
|
||||
isGlobalStatic(),
|
||||
// ... that have C++ constructors...
|
||||
hasDescendant(cxxConstructExpr(unless(allOf(
|
||||
// ... unless it is constexpr ...
|
||||
hasDeclaration(cxxConstructorDecl(isConstexpr())),
|
||||
// ... and is statically initialized.
|
||||
isConstantInitializer()))))))
|
||||
.bind("decl"),
|
||||
this);
|
||||
Finder->addMatcher(varDecl(
|
||||
// Match global, statically stored objects...
|
||||
isGlobalStatic(),
|
||||
// ... that have C++ constructors...
|
||||
hasDescendant(cxxConstructExpr(unless(allOf(
|
||||
// ... unless it is constexpr ...
|
||||
hasDeclaration(cxxConstructorDecl(isConstexpr())),
|
||||
// ... and is statically initialized.
|
||||
isConstantInitializer())))))
|
||||
.bind("decl"),
|
||||
this);
|
||||
}
|
||||
|
||||
void StaticallyConstructedObjectsCheck::check(
|
||||
|
||||
@@ -34,9 +34,9 @@ void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// using decltype specifiers and lambda with otherwise unutterable
|
||||
// return types.
|
||||
Finder->addMatcher(
|
||||
functionDecl(allOf(hasTrailingReturn(),
|
||||
unless(anyOf(returns(decltypeType()),
|
||||
hasParent(cxxRecordDecl(isLambda()))))))
|
||||
functionDecl(hasTrailingReturn(),
|
||||
unless(anyOf(returns(decltypeType()),
|
||||
hasParent(cxxRecordDecl(isLambda())))))
|
||||
.bind("decl"),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -33,12 +33,10 @@ void OverloadedUnaryAndCheck::registerMatchers(
|
||||
this);
|
||||
// Also match freestanding unary operator& overloads. Be careful not to match
|
||||
// binary methods.
|
||||
Finder->addMatcher(
|
||||
functionDecl(allOf(
|
||||
unless(cxxMethodDecl()),
|
||||
functionDecl(parameterCountIs(1), hasOverloadedOperatorName("&"))
|
||||
.bind("overload"))),
|
||||
this);
|
||||
Finder->addMatcher(functionDecl(unless(cxxMethodDecl()), parameterCountIs(1),
|
||||
hasOverloadedOperatorName("&"))
|
||||
.bind("overload"),
|
||||
this);
|
||||
}
|
||||
|
||||
void OverloadedUnaryAndCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
||||
@@ -23,22 +23,21 @@ void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
Finder->addMatcher(
|
||||
cxxThrowExpr(
|
||||
allOf(
|
||||
unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))),
|
||||
// The thrown value is not derived from 'std::exception'.
|
||||
has(expr(unless(hasType(
|
||||
qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
|
||||
isSameOrDerivedFrom(hasName("::std::exception")))))))))),
|
||||
// This condition is always true, but will bind to the
|
||||
// template value if the thrown type is templated.
|
||||
anyOf(has(expr(hasType(
|
||||
substTemplateTypeParmType().bind("templ_type")))),
|
||||
anything()),
|
||||
// Bind to the declaration of the type of the value that
|
||||
// is thrown. 'anything()' is necessary to always suceed
|
||||
// in the 'eachOf' because builtin types are not
|
||||
// 'namedDecl'.
|
||||
eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything())))
|
||||
unless(has(expr(anyOf(isTypeDependent(), isValueDependent())))),
|
||||
// The thrown value is not derived from 'std::exception'.
|
||||
has(expr(unless(
|
||||
hasType(qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(
|
||||
isSameOrDerivedFrom(hasName("::std::exception")))))))))),
|
||||
// This condition is always true, but will bind to the
|
||||
// template value if the thrown type is templated.
|
||||
anyOf(has(expr(
|
||||
hasType(substTemplateTypeParmType().bind("templ_type")))),
|
||||
anything()),
|
||||
// Bind to the declaration of the type of the value that
|
||||
// is thrown. 'anything()' is necessary to always suceed
|
||||
// in the 'eachOf' because builtin types are not
|
||||
// 'namedDecl'.
|
||||
eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything()))
|
||||
.bind("bad_throw"),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void MultiwayPathsCoveredCheck::storeOptions(
|
||||
void MultiwayPathsCoveredCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
switchStmt(
|
||||
hasCondition(allOf(
|
||||
hasCondition(expr(
|
||||
// Match on switch statements that have either a bit-field or
|
||||
// an integer condition. The ordering in 'anyOf()' is
|
||||
// important because the last condition is the most general.
|
||||
@@ -43,10 +43,9 @@ void MultiwayPathsCoveredCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
// This option is noisy, therefore matching is configurable.
|
||||
if (WarnOnMissingElse) {
|
||||
Finder->addMatcher(
|
||||
ifStmt(allOf(hasParent(ifStmt()), unless(hasElse(anything()))))
|
||||
.bind("else-if"),
|
||||
this);
|
||||
Finder->addMatcher(ifStmt(hasParent(ifStmt()), unless(hasElse(anything())))
|
||||
.bind("else-if"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,42 +26,40 @@ void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// as signed types. Exclude these types from diagnosing for bitwise or(|) and
|
||||
// bitwise and(&). Shifting and complementing such values is still not
|
||||
// allowed.
|
||||
const auto BitmaskType = namedDecl(anyOf(
|
||||
hasName("::std::locale::category"), hasName("::std::ctype_base::mask"),
|
||||
hasName("::std::ios_base::fmtflags"), hasName("::std::ios_base::iostate"),
|
||||
hasName("::std::ios_base::openmode")));
|
||||
const auto BitmaskType = namedDecl(
|
||||
hasAnyName("::std::locale::category", "::std::ctype_base::mask",
|
||||
"::std::ios_base::fmtflags", "::std::ios_base::iostate",
|
||||
"::std::ios_base::openmode"));
|
||||
const auto IsStdBitmask = ignoringImpCasts(declRefExpr(hasType(BitmaskType)));
|
||||
|
||||
// Match binary bitwise operations on signed integer arguments.
|
||||
Finder->addMatcher(
|
||||
binaryOperator(
|
||||
allOf(anyOf(hasOperatorName("^"), hasOperatorName("|"),
|
||||
hasOperatorName("&"), hasOperatorName("^="),
|
||||
hasOperatorName("|="), hasOperatorName("&=")),
|
||||
binaryOperator(anyOf(hasOperatorName("^"), hasOperatorName("|"),
|
||||
hasOperatorName("&"), hasOperatorName("^="),
|
||||
hasOperatorName("|="), hasOperatorName("&=")),
|
||||
|
||||
unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
|
||||
unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
|
||||
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger())))
|
||||
.bind("binary-no-sign-interference"),
|
||||
this);
|
||||
|
||||
// Shifting and complement is not allowed for any signed integer type because
|
||||
// the sign bit may corrupt the result.
|
||||
Finder->addMatcher(
|
||||
binaryOperator(
|
||||
allOf(anyOf(hasOperatorName("<<"), hasOperatorName(">>"),
|
||||
hasOperatorName("<<="), hasOperatorName(">>=")),
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
|
||||
binaryOperator(anyOf(hasOperatorName("<<"), hasOperatorName(">>"),
|
||||
hasOperatorName("<<="), hasOperatorName(">>=")),
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger())))
|
||||
.bind("binary-sign-interference"),
|
||||
this);
|
||||
|
||||
// Match unary operations on signed integer types.
|
||||
Finder->addMatcher(unaryOperator(allOf(hasOperatorName("~"),
|
||||
hasUnaryOperand(SignedIntegerOperand)))
|
||||
.bind("unary-signed"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
unaryOperator(hasOperatorName("~"), hasUnaryOperand(SignedIntegerOperand))
|
||||
.bind("unary-signed"),
|
||||
this);
|
||||
}
|
||||
|
||||
void SignedBitwiseCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
||||
@@ -59,13 +59,6 @@ void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
|
||||
allOf(boolean(IgnoreClassesWithAllMemberVariablesBeingPublic),
|
||||
unless(hasNonPublicMemberVariable()));
|
||||
|
||||
// We only want the records that not only contain the mutable data (non-static
|
||||
// member variables), but also have some logic (non-static member functions).
|
||||
// We may optionally ignore records where all the member variables are public.
|
||||
auto RecordIsInteresting =
|
||||
allOf(anyOf(isStruct(), isClass()), hasMethods(), hasNonStaticMethod(),
|
||||
unless(ShouldIgnoreRecord));
|
||||
|
||||
// There are three visibility types: public, protected, private.
|
||||
// If we are ok with public fields, then we only want to complain about
|
||||
// protected fields, else we want to complain about all non-private fields.
|
||||
@@ -73,7 +66,12 @@ void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
|
||||
auto InterestingField = fieldDecl(
|
||||
IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
|
||||
|
||||
Finder->addMatcher(cxxRecordDecl(RecordIsInteresting,
|
||||
// We only want the records that not only contain the mutable data (non-static
|
||||
// member variables), but also have some logic (non-static member functions).
|
||||
// We may optionally ignore records where all the member variables are public.
|
||||
Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(),
|
||||
hasNonStaticMethod(),
|
||||
unless(ShouldIgnoreRecord),
|
||||
forEach(InterestingField.bind("field")))
|
||||
.bind("record"),
|
||||
this);
|
||||
|
||||
@@ -162,7 +162,7 @@ StatementMatcher makeIteratorLoopMatcher() {
|
||||
// reference then the return type is tagged with DerefByValueResultName.
|
||||
internal::Matcher<VarDecl> TestDerefReturnsByValue =
|
||||
hasType(hasUnqualifiedDesugaredType(
|
||||
recordType(hasDeclaration(cxxRecordDecl(hasMethod(allOf(
|
||||
recordType(hasDeclaration(cxxRecordDecl(hasMethod(cxxMethodDecl(
|
||||
hasOverloadedOperatorName("*"),
|
||||
anyOf(
|
||||
// Tag the return type if it's by value.
|
||||
|
||||
@@ -109,7 +109,7 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
// using std::auto_ptr;
|
||||
// ^~~~~~~~~~~~~~~~~~~
|
||||
Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(allOf(
|
||||
Finder->addMatcher(usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(namedDecl(
|
||||
hasName("auto_ptr"), isFromStdNamespace()))))
|
||||
.bind(AutoPtrTokenId),
|
||||
this);
|
||||
|
||||
@@ -211,7 +211,7 @@ AST_POLYMORPHIC_MATCHER(hasExplicitTemplateArgs,
|
||||
/// \brief Returns a DeclarationMatcher that matches standard iterators nested
|
||||
/// inside records with a standard container name.
|
||||
DeclarationMatcher standardIterator() {
|
||||
return allOf(
|
||||
return decl(
|
||||
namedDecl(hasStdIteratorName()),
|
||||
hasDeclContext(recordDecl(hasStdContainerName(), isFromStdNamespace())));
|
||||
}
|
||||
@@ -233,7 +233,7 @@ TypeMatcher nestedIterator() {
|
||||
TypeMatcher iteratorFromUsingDeclaration() {
|
||||
auto HasIteratorDecl = hasDeclaration(namedDecl(hasStdIteratorName()));
|
||||
// Types resulting from using declarations are represented by elaboratedType.
|
||||
return elaboratedType(allOf(
|
||||
return elaboratedType(
|
||||
// Unwrap the nested name specifier to test for one of the standard
|
||||
// containers.
|
||||
hasQualifier(specifiesType(templateSpecializationType(hasDeclaration(
|
||||
@@ -241,7 +241,7 @@ TypeMatcher iteratorFromUsingDeclaration() {
|
||||
// the named type is what comes after the final '::' in the type. It
|
||||
// should name one of the standard iterator names.
|
||||
namesType(
|
||||
anyOf(typedefType(HasIteratorDecl), recordType(HasIteratorDecl)))));
|
||||
anyOf(typedefType(HasIteratorDecl), recordType(HasIteratorDecl))));
|
||||
}
|
||||
|
||||
/// \brief This matcher returns declaration statements that contain variable
|
||||
|
||||
@@ -77,12 +77,12 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context,
|
||||
if (match(
|
||||
cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer(
|
||||
isBaseInitializer(),
|
||||
withInitializer(cxxConstructExpr(allOf(
|
||||
withInitializer(cxxConstructExpr(
|
||||
hasType(equalsNode(Base)),
|
||||
hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
|
||||
argumentCountIs(1),
|
||||
hasArgument(
|
||||
0, declRefExpr(to(varDecl(equalsNode(Param))))))))))),
|
||||
0, declRefExpr(to(varDecl(equalsNode(Param)))))))))),
|
||||
*Ctor, *Context)
|
||||
.empty())
|
||||
return false;
|
||||
@@ -98,10 +98,10 @@ static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context,
|
||||
withInitializer(anyOf(
|
||||
AccessToFieldInParam,
|
||||
initListExpr(has(AccessToFieldInParam)),
|
||||
cxxConstructExpr(allOf(
|
||||
cxxConstructExpr(
|
||||
hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
|
||||
argumentCountIs(1),
|
||||
hasArgument(0, AccessToFieldInParam)))))))),
|
||||
hasArgument(0, AccessToFieldInParam))))))),
|
||||
*Ctor, *Context)
|
||||
.empty())
|
||||
return false;
|
||||
@@ -145,21 +145,21 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context,
|
||||
// ((Base*)this)->operator=((Base)Other);
|
||||
//
|
||||
// So we are looking for a member call that fulfills:
|
||||
if (match(compoundStmt(has(ignoringParenImpCasts(cxxMemberCallExpr(allOf(
|
||||
// - The object is an implicit cast of 'this' to a pointer to
|
||||
// a base class.
|
||||
onImplicitObjectArgument(
|
||||
implicitCastExpr(hasImplicitDestinationType(
|
||||
pointsTo(type(equalsNode(Base)))),
|
||||
hasSourceExpression(cxxThisExpr()))),
|
||||
// - The called method is the operator=.
|
||||
callee(cxxMethodDecl(isCopyAssignmentOperator())),
|
||||
// - The argument is (an implicit cast to a Base of) the
|
||||
// argument taken by "Operator".
|
||||
argumentCountIs(1),
|
||||
hasArgument(0,
|
||||
declRefExpr(to(varDecl(equalsNode(Param)))))))))),
|
||||
*Compound, *Context)
|
||||
if (match(
|
||||
compoundStmt(has(ignoringParenImpCasts(cxxMemberCallExpr(
|
||||
// - The object is an implicit cast of 'this' to a pointer to
|
||||
// a base class.
|
||||
onImplicitObjectArgument(
|
||||
implicitCastExpr(hasImplicitDestinationType(
|
||||
pointsTo(type(equalsNode(Base)))),
|
||||
hasSourceExpression(cxxThisExpr()))),
|
||||
// - The called method is the operator=.
|
||||
callee(cxxMethodDecl(isCopyAssignmentOperator())),
|
||||
// - The argument is (an implicit cast to a Base of) the
|
||||
// argument taken by "Operator".
|
||||
argumentCountIs(1),
|
||||
hasArgument(0, declRefExpr(to(varDecl(equalsNode(Param))))))))),
|
||||
*Compound, *Context)
|
||||
.empty())
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,24 +30,22 @@ void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
this);
|
||||
|
||||
// DeclRefExpr: warning, no fix-it.
|
||||
Finder->addMatcher(declRefExpr(allOf(to(functionDecl(hasName(MatchText))),
|
||||
unless(callExpr())))
|
||||
.bind("decl_ref_expr"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
declRefExpr(to(functionDecl(hasName(MatchText))), unless(callExpr()))
|
||||
.bind("decl_ref_expr"),
|
||||
this);
|
||||
|
||||
// CallExpr: warning, fix-it.
|
||||
Finder->addMatcher(
|
||||
callExpr(allOf(hasDeclaration(functionDecl(hasName(MatchText))),
|
||||
unless(hasAncestor(initListExpr()))))
|
||||
.bind("call_expr"),
|
||||
this);
|
||||
Finder->addMatcher(callExpr(hasDeclaration(functionDecl(hasName(MatchText))),
|
||||
unless(hasAncestor(initListExpr())))
|
||||
.bind("call_expr"),
|
||||
this);
|
||||
// CallExpr in initialisation list: warning, fix-it with avoiding narrowing
|
||||
// conversions.
|
||||
Finder->addMatcher(
|
||||
callExpr(allOf(hasAncestor(initListExpr()),
|
||||
hasDeclaration(functionDecl(hasName(MatchText)))))
|
||||
.bind("init_call_expr"),
|
||||
this);
|
||||
Finder->addMatcher(callExpr(hasAncestor(initListExpr()),
|
||||
hasDeclaration(functionDecl(hasName(MatchText))))
|
||||
.bind("init_call_expr"),
|
||||
this);
|
||||
}
|
||||
|
||||
void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
||||
@@ -35,14 +35,12 @@ void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
Finder->addMatcher(
|
||||
cxxConstructorDecl(
|
||||
unless(isImplicit()),
|
||||
allOf(isMoveConstructor(),
|
||||
hasAnyConstructorInitializer(
|
||||
cxxCtorInitializer(
|
||||
withInitializer(cxxConstructExpr(hasDeclaration(
|
||||
cxxConstructorDecl(isCopyConstructor())
|
||||
.bind("ctor")))))
|
||||
.bind("move-init")))),
|
||||
unless(isImplicit()), isMoveConstructor(),
|
||||
hasAnyConstructorInitializer(
|
||||
cxxCtorInitializer(
|
||||
withInitializer(cxxConstructExpr(hasDeclaration(
|
||||
cxxConstructorDecl(isCopyConstructor()).bind("ctor")))))
|
||||
.bind("move-init"))),
|
||||
this);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,6 @@ UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
|
||||
|
||||
void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
|
||||
auto ConstReference = referenceType(pointee(qualType(isConstQualified())));
|
||||
auto ConstOrConstReference =
|
||||
allOf(anyOf(ConstReference, isConstQualified()),
|
||||
unless(allOf(pointerType(), unless(pointerType(pointee(
|
||||
qualType(isConstQualified())))))));
|
||||
|
||||
// Match method call expressions where the `this` argument is only used as
|
||||
// const, this will be checked in `check()` part. This returned const
|
||||
@@ -63,11 +59,11 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
|
||||
declStmt(
|
||||
has(varDecl(hasLocalStorage(),
|
||||
hasType(qualType(
|
||||
allOf(hasCanonicalType(
|
||||
matchers::isExpensiveToCopy()),
|
||||
unless(hasDeclaration(namedDecl(
|
||||
matchers::matchesAnyListedName(
|
||||
AllowedTypes))))))),
|
||||
hasCanonicalType(
|
||||
matchers::isExpensiveToCopy()),
|
||||
unless(hasDeclaration(namedDecl(
|
||||
matchers::matchesAnyListedName(
|
||||
AllowedTypes)))))),
|
||||
unless(isImplicit()),
|
||||
hasInitializer(
|
||||
cxxConstructExpr(
|
||||
|
||||
@@ -79,11 +79,11 @@ void UnnecessaryValueParamCheck::registerMatchers(MatchFinder *Finder) {
|
||||
if (!getLangOpts().CPlusPlus)
|
||||
return;
|
||||
const auto ExpensiveValueParamDecl = parmVarDecl(
|
||||
hasType(qualType(allOf(
|
||||
hasType(qualType(
|
||||
hasCanonicalType(matchers::isExpensiveToCopy()),
|
||||
unless(anyOf(hasCanonicalType(referenceType()),
|
||||
hasDeclaration(namedDecl(
|
||||
matchers::matchesAnyListedName(AllowedTypes)))))))),
|
||||
matchers::matchesAnyListedName(AllowedTypes))))))),
|
||||
decl().bind("param"));
|
||||
Finder->addMatcher(
|
||||
functionDecl(hasBody(stmt()), isDefinition(), unless(isImplicit()),
|
||||
|
||||
@@ -100,9 +100,9 @@ void SIMDIntrinsicsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
if (Std.empty())
|
||||
Std = getLangOpts().CPlusPlus2a ? "std" : "std::experimental";
|
||||
|
||||
Finder->addMatcher(callExpr(callee(functionDecl(allOf(
|
||||
Finder->addMatcher(callExpr(callee(functionDecl(
|
||||
matchesName("^::(_mm_|_mm256_|_mm512_|vec_)"),
|
||||
isVectorFunction()))),
|
||||
isVectorFunction())),
|
||||
unless(isExpansionInSystemHeader()))
|
||||
.bind("call"),
|
||||
this);
|
||||
|
||||
@@ -26,11 +26,10 @@ AST_MATCHER(DeclStmt, onlyDeclaresVariables) {
|
||||
} // namespace
|
||||
|
||||
void IsolateDeclarationCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
declStmt(allOf(onlyDeclaresVariables(), unless(isSingleDecl()),
|
||||
hasParent(compoundStmt())))
|
||||
.bind("decl_stmt"),
|
||||
this);
|
||||
Finder->addMatcher(declStmt(onlyDeclaresVariables(), unless(isSingleDecl()),
|
||||
hasParent(compoundStmt()))
|
||||
.bind("decl_stmt"),
|
||||
this);
|
||||
}
|
||||
|
||||
static SourceLocation findStartOfIndirection(SourceLocation Start,
|
||||
|
||||
@@ -491,12 +491,12 @@ void SimplifyBooleanExprCheck::matchCompoundIfReturnsBool(MatchFinder *Finder,
|
||||
bool Value,
|
||||
StringRef Id) {
|
||||
Finder->addMatcher(
|
||||
compoundStmt(allOf(hasAnySubstatement(ifStmt(hasThen(returnsBool(Value)),
|
||||
unless(hasElse(stmt())))),
|
||||
hasAnySubstatement(
|
||||
returnStmt(has(ignoringParenImpCasts(
|
||||
compoundStmt(
|
||||
hasAnySubstatement(
|
||||
ifStmt(hasThen(returnsBool(Value)), unless(hasElse(stmt())))),
|
||||
hasAnySubstatement(returnStmt(has(ignoringParenImpCasts(
|
||||
cxxBoolLiteral(equals(!Value)))))
|
||||
.bind(CompoundReturnId))))
|
||||
.bind(CompoundReturnId)))
|
||||
.bind(Id),
|
||||
this);
|
||||
}
|
||||
|
||||
@@ -196,11 +196,11 @@ void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// E.g. i32 suffix still results in 'BuiltinType::Kind::Int'.
|
||||
// And such an info is not stored in the *Literal itself.
|
||||
Finder->addMatcher(
|
||||
stmt(allOf(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
|
||||
floatLiteral().bind(FloatingLiteralCheck::Name)),
|
||||
unless(anyOf(hasParent(userDefinedLiteral()),
|
||||
hasAncestor(isImplicit()),
|
||||
hasAncestor(substNonTypeTemplateParmExpr()))))),
|
||||
stmt(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
|
||||
floatLiteral().bind(FloatingLiteralCheck::Name)),
|
||||
unless(anyOf(hasParent(userDefinedLiteral()),
|
||||
hasAncestor(isImplicit()),
|
||||
hasAncestor(substNonTypeTemplateParmExpr())))),
|
||||
this);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ void TemporaryObjectsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
// Matcher for user-defined constructors.
|
||||
Finder->addMatcher(
|
||||
cxxConstructExpr(allOf(hasParent(cxxFunctionalCastExpr()),
|
||||
hasDeclaration(cxxConstructorDecl(hasParent(
|
||||
cxxRecordDecl(matchesAnyName(Names)))))))
|
||||
cxxConstructExpr(hasParent(cxxFunctionalCastExpr()),
|
||||
hasDeclaration(cxxConstructorDecl(
|
||||
hasParent(cxxRecordDecl(matchesAnyName(Names))))))
|
||||
.bind("temps"),
|
||||
this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user