Author: Victor Chernyakin Date: 2026-02-01T16:26:41-08:00 New Revision: 9e5deb963abec2808152b55d826333cba8ad5ab0
URL: https://github.com/llvm/llvm-project/commit/9e5deb963abec2808152b55d826333cba8ad5ab0 DIFF: https://github.com/llvm/llvm-project/commit/9e5deb963abec2808152b55d826333cba8ad5ab0.diff LOG: [clang-tidy] Speed up `modernize-use-nullptr` (#178829) As noted in [this comment](https://github.com/llvm/llvm-project/pull/178149#discussion_r2732896149), it appears that registering one `anyOf(a, b, ...)` matcher is generally slower than registering `a, b, ...` all individually. Applying that knowledge to this check gives us an easy 3x speedup: ```txt ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- Status quo: 0.3281 ( 6.1%) 0.0469 ( 5.2%) 0.3750 ( 6.0%) 0.3491 ( 5.5%) modernize-use-nullptr With this change: 0.0938 ( 1.8%) 0.0156 ( 1.8%) 0.1094 ( 1.8%) 0.1260 ( 2.1%) modernize-use-nullptr ``` I'm not exactly sure *why* this works, but it seems pretty consistent. I've seen a similar result trying this with `bugprone-infinite-loop`. Added: Modified: clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp index cc371a1ab55a7..85224b573edeb 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -45,8 +45,7 @@ static constexpr char CastSequence[] = "sequence"; /// would check for the "NULL" macro instead, but that'd be harder to express. /// In practice, "NULL" is often defined as "__null", and this is a useful /// condition. -static StatementMatcher -makeCastSequenceMatcher(llvm::ArrayRef<StringRef> NameList) { +void UseNullptrCheck::registerMatchers(MatchFinder *Finder) { auto ImplicitCastToNull = implicitCastExpr( anyOf(hasCastKind(CK_NullToPointer), hasCastKind(CK_NullToMemberPointer)), anyOf(hasSourceExpression(gnuNullExpr()), @@ -54,32 +53,34 @@ makeCastSequenceMatcher(llvm::ArrayRef<StringRef> NameList) { qualType(substTemplateTypeParmType())))), unless(hasSourceExpression(hasType(sugaredNullptrType()))), unless(hasImplicitDestinationType( - qualType(matchers::matchesAnyListedTypeName(NameList))))); + qualType(matchers::matchesAnyListedTypeName(IgnoredTypes))))); auto IsOrHasDescendant = [](const auto &InnerMatcher) { return anyOf(InnerMatcher, hasDescendant(InnerMatcher)); }; - return traverse( - TK_AsIs, - anyOf(castExpr(anyOf(ImplicitCastToNull, - explicitCastExpr(hasDescendant(ImplicitCastToNull))), - unless(hasAncestor(explicitCastExpr())), - unless(hasAncestor(cxxRewrittenBinaryOperator()))) - .bind(CastSequence), - cxxRewrittenBinaryOperator( - // Match rewritten operators, but verify (in the check method) - // that if an implicit cast is found, it is not from another - // nested rewritten operator. - expr().bind("matchBinopOperands"), - hasEitherOperand(IsOrHasDescendant( - implicitCastExpr( - ImplicitCastToNull, - hasAncestor(cxxRewrittenBinaryOperator().bind( - "checkBinopOperands"))) - .bind(CastSequence))), - // Skip defaulted comparison operators. - unless(hasAncestor(functionDecl(isDefaulted())))))); + Finder->addMatcher( + castExpr(anyOf(ImplicitCastToNull, + explicitCastExpr(hasDescendant(ImplicitCastToNull))), + unless(hasAncestor(explicitCastExpr())), + unless(hasAncestor(cxxRewrittenBinaryOperator()))) + .bind(CastSequence), + this); + + Finder->addMatcher( + cxxRewrittenBinaryOperator( + // Match rewritten operators, but verify (in the check method) + // that if an implicit cast is found, it is not from another + // nested rewritten operator. + expr().bind("matchBinopOperands"), + hasEitherOperand(IsOrHasDescendant( + implicitCastExpr(ImplicitCastToNull, + hasAncestor(cxxRewrittenBinaryOperator().bind( + "checkBinopOperands"))) + .bind(CastSequence))), + // Skip defaulted comparison operators. + unless(hasAncestor(functionDecl(isDefaulted())))), + this); } static bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc, @@ -505,10 +506,6 @@ void UseNullptrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { utils::options::serializeStringList(IgnoredTypes)); } -void UseNullptrCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(makeCastSequenceMatcher(IgnoredTypes), this); -} - void UseNullptrCheck::check(const MatchFinder::MatchResult &Result) { const auto *NullCast = Result.Nodes.getNodeAs<CastExpr>(CastSequence); assert(NullCast && "Bad Callback. No node provided"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
