diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.h @@ -33,6 +33,9 @@ } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } }; } // namespace readability diff --git a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -83,6 +83,9 @@ }); return Result; } +AST_MATCHER(CXXConstructExpr, isDefaultConstruction) { + return Node.getConstructor()->isDefaultConstructor(); +} } // namespace ast_matchers namespace tidy { namespace readability { @@ -116,24 +119,16 @@ const auto ValidContainer = qualType( anyOf(ValidContainerNonTemplateType, ValidContainerTemplateType)); - const auto WrongUse = traverse( - TK_AsIs, - anyOf( - hasParent(binaryOperator(isComparisonOperator(), - hasEitherOperand(ignoringImpCasts( - anyOf(integerLiteral(equals(1)), - integerLiteral(equals(0)))))) - .bind("SizeBinaryOp")), - hasParent(implicitCastExpr( - hasImplicitDestinationType(booleanType()), - anyOf(hasParent( - unaryOperator(hasOperatorName("!")).bind("NegOnSize")), - anything()))), - usedInBooleanContext())); + const auto WrongUse = + anyOf(hasParent(binaryOperator( + isComparisonOperator(), + hasEitherOperand(anyOf(integerLiteral(equals(1)), + integerLiteral(equals(0))))) + .bind("SizeBinaryOp")), + usedInBooleanContext()); Finder->addMatcher( - cxxMemberCallExpr(unless(isInTemplateInstantiation()), - on(expr(anyOf(hasType(ValidContainer), + cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer), hasType(pointsTo(ValidContainer)), hasType(references(ValidContainer)))) .bind("MemberCallObject")), @@ -157,18 +152,9 @@ .bind("SizeCallExpr"), this); - // Empty constructor matcher. - const auto DefaultConstructor = cxxConstructExpr( - hasDeclaration(cxxConstructorDecl(isDefaultConstructor()))); // Comparison to empty string or empty constructor. const auto WrongComparend = anyOf( - ignoringImpCasts(stringLiteral(hasSize(0))), - ignoringImpCasts(cxxBindTemporaryExpr(has(DefaultConstructor))), - ignoringImplicit(DefaultConstructor), - cxxConstructExpr(hasDeclaration(cxxConstructorDecl(isCopyConstructor())), - has(expr(ignoringImpCasts(DefaultConstructor)))), - cxxConstructExpr(hasDeclaration(cxxConstructorDecl(isMoveConstructor())), - has(expr(ignoringImpCasts(DefaultConstructor)))), + stringLiteral(hasSize(0)), cxxConstructExpr(isDefaultConstruction()), cxxUnresolvedConstructExpr(argumentCountIs(0))); // Match the object being compared. const auto STLArg = @@ -178,12 +164,11 @@ expr(hasType(pointsTo(ValidContainer))).bind("Pointee"))), expr(hasType(ValidContainer)).bind("STLObject")); Finder->addMatcher( - binaryOperation(unless(isInTemplateInstantiation()), - hasAnyOperatorName("==", "!="), - hasOperands(ignoringParenImpCasts(WrongComparend), - ignoringParenImpCasts(STLArg)), - unless(hasAncestor(cxxMethodDecl( - ofClass(equalsBoundNode("container")))))) + binaryOperation(hasAnyOperatorName("==", "!="), + hasOperands(WrongComparend, + STLArg), + unless(hasAncestor(cxxMethodDecl( + ofClass(equalsBoundNode("container")))))) .bind("BinCmp"), this); } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp @@ -477,9 +477,6 @@ struct StructWithLazyNoexcept { void func() noexcept(L.size()); -// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: the 'empty' method should be used -// CHECK-MESSAGES: :101:18: note: method 'Lazy'::empty() defined here -// CHECK-FIXES: {{^ }}void func() noexcept(!L.empty()); }; #define CHECKSIZE(x) if (x.size()) {}