From 1087db5b1f80d1f5dc70a93c63d7ec8f19425b9b Mon Sep 17 00:00:00 2001 From: Victor Chernyakin Date: Sat, 21 Mar 2026 00:29:07 -0500 Subject: [PATCH] [clang-tidy] Speed up `bugprone-suspicious-semicolon` (#187558) ```txt ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- Status quo: 0.4743 (100.0%) 0.3802 (100.0%) 0.8546 (100.0%) 0.8567 (100.0%) bugprone-suspicious-semicolon With this change: 0.0103 (100.0%) 0.0027 (100.0%) 0.0130 (100.0%) 0.0133 (100.0%) bugprone-suspicious-semicolon ``` Continuing the trend of registering one `anyOf` matcher being slower than registering each of its matchers separately (see #178829 for a previous example). (This PR also changes the traversal mode, but I only saw a small speedup from that. Most of it came from registering the matchers separately.) This check wasn't super expensive to begin with, but the speedup is still pretty nice. --- .../bugprone/SuspiciousSemicolonCheck.cpp | 16 +++++++++------- .../bugprone/SuspiciousSemicolonCheck.h | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp index 94041c326038..ee2a4638f0a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp @@ -16,14 +16,16 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { void SuspiciousSemicolonCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(ifStmt(hasThen(nullStmt().bind("semi")), + unless(hasElse(stmt())), unless(isConstexpr())) + .bind("stmt"), + this); + Finder->addMatcher(forStmt(hasBody(nullStmt().bind("semi"))).bind("stmt"), + this); Finder->addMatcher( - stmt(anyOf(ifStmt(hasThen(nullStmt().bind("semi")), - unless(hasElse(stmt())), unless(isConstexpr())), - forStmt(hasBody(nullStmt().bind("semi"))), - cxxForRangeStmt(hasBody(nullStmt().bind("semi"))), - whileStmt(hasBody(nullStmt().bind("semi"))))) - .bind("stmt"), - this); + cxxForRangeStmt(hasBody(nullStmt().bind("semi"))).bind("stmt"), this); + Finder->addMatcher(whileStmt(hasBody(nullStmt().bind("semi"))).bind("stmt"), + this); } void SuspiciousSemicolonCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.h b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.h index 10bdf328df0f..e789d5bfa4cc 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.h @@ -24,6 +24,9 @@ public: : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } }; } // namespace clang::tidy::bugprone