https://github.com/localspook updated 
https://github.com/llvm/llvm-project/pull/184069

>From 170fffed2bd9a7a780c92da7c895df511efe66fc Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Sun, 1 Mar 2026 22:07:12 -0800
Subject: [PATCH 1/3] [clang-tidy] Centralize the logic for matching discarded
 expressions

---
 .../bugprone/StandaloneEmptyCheck.cpp         | 113 +++---------------
 .../bugprone/ThrowKeywordMissingCheck.cpp     |  20 +---
 .../clang-tidy/bugprone/UnusedRaiiCheck.cpp   |  23 ++--
 .../bugprone/UnusedReturnValueCheck.cpp       |  29 +----
 .../clang-tidy/modernize/UseStdPrintCheck.cpp |  52 +++-----
 clang-tools-extra/clang-tidy/utils/Matchers.h |  57 +++++++++
 .../checkers/modernize/use-std-print.cpp      |   5 +
 7 files changed, 112 insertions(+), 187 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp
index 056ae4b80f109..7d787c361c8a5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp
@@ -7,86 +7,29 @@
 
//===----------------------------------------------------------------------===//
 
 #include "StandaloneEmptyCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/Type.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "../utils/Matchers.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Sema/HeuristicResolver.h"
-#include "llvm/Support/Casting.h"
 
-namespace clang::tidy::bugprone {
+using namespace clang::ast_matchers;
 
-using ast_matchers::BoundNodes;
-using ast_matchers::callee;
-using ast_matchers::callExpr;
-using ast_matchers::classTemplateDecl;
-using ast_matchers::cxxMemberCallExpr;
-using ast_matchers::cxxMethodDecl;
-using ast_matchers::expr;
-using ast_matchers::functionDecl;
-using ast_matchers::hasAncestor;
-using ast_matchers::hasName;
-using ast_matchers::hasParent;
-using ast_matchers::ignoringImplicit;
-using ast_matchers::ignoringParenImpCasts;
-using ast_matchers::MatchFinder;
-using ast_matchers::optionally;
-using ast_matchers::returns;
-using ast_matchers::stmt;
-using ast_matchers::stmtExpr;
-using ast_matchers::unless;
-using ast_matchers::voidType;
-
-static const Expr *getCondition(const BoundNodes &Nodes,
-                                const StringRef NodeId) {
-  const auto *If = Nodes.getNodeAs<IfStmt>(NodeId);
-  if (If != nullptr)
-    return If->getCond();
-
-  const auto *For = Nodes.getNodeAs<ForStmt>(NodeId);
-  if (For != nullptr)
-    return For->getCond();
-
-  const auto *While = Nodes.getNodeAs<WhileStmt>(NodeId);
-  if (While != nullptr)
-    return While->getCond();
-
-  const auto *Do = Nodes.getNodeAs<DoStmt>(NodeId);
-  if (Do != nullptr)
-    return Do->getCond();
-
-  const auto *Switch = Nodes.getNodeAs<SwitchStmt>(NodeId);
-  if (Switch != nullptr)
-    return Switch->getCond();
-
-  return nullptr;
-}
+namespace clang::tidy::bugprone {
 
-void StandaloneEmptyCheck::registerMatchers(ast_matchers::MatchFinder *Finder) 
{
+void StandaloneEmptyCheck::registerMatchers(MatchFinder *Finder) {
   // Ignore empty calls in a template definition which fall under callExpr
   // non-member matcher even if they are methods.
-  const auto NonMemberMatcher = expr(ignoringImplicit(ignoringParenImpCasts(
-      callExpr(
-          hasParent(stmt(optionally(hasParent(stmtExpr().bind("stexpr"))))
-                        .bind("parent")),
-          unless(hasAncestor(classTemplateDecl())),
-          callee(functionDecl(hasName("empty"), unless(returns(voidType())))))
-          .bind("empty"))));
+  const auto NonMemberMatcher =
+      expr(ignoringParenImpCasts(
+               callExpr(unless(hasAncestor(classTemplateDecl())),
+                        callee(functionDecl(hasName("empty"),
+                                            unless(returns(voidType())))))
+                   .bind("empty")),
+           matchers::isDiscarded());
   const auto MemberMatcher =
-      expr(ignoringImplicit(ignoringParenImpCasts(cxxMemberCallExpr(
-               hasParent(stmt(optionally(hasParent(stmtExpr().bind("stexpr"))))
-                             .bind("parent")),
-               callee(cxxMethodDecl(hasName("empty"),
-                                    unless(returns(voidType()))))))))
+      expr(ignoringParenImpCasts(cxxMemberCallExpr(callee(
+               cxxMethodDecl(hasName("empty"), unless(returns(voidType())))))),
+           matchers::isDiscarded())
           .bind("empty");
 
   Finder->addMatcher(MemberMatcher, this);
@@ -94,29 +37,8 @@ void 
StandaloneEmptyCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
 }
 
 void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) {
-  // Skip if the parent node is Expr.
-  if (Result.Nodes.getNodeAs<Expr>("parent"))
-    return;
-
-  const auto *PParentStmtExpr = Result.Nodes.getNodeAs<Expr>("stexpr");
-  const auto *ParentCompStmt = Result.Nodes.getNodeAs<CompoundStmt>("parent");
-  const auto *ParentCond = getCondition(Result.Nodes, "parent");
-  const auto *ParentReturnStmt = Result.Nodes.getNodeAs<ReturnStmt>("parent");
-
   if (const auto *MemberCall =
           Result.Nodes.getNodeAs<CXXMemberCallExpr>("empty")) {
-    // Skip if it's a condition of the parent statement.
-    if (ParentCond == MemberCall->getExprStmt())
-      return;
-    // Skip if it's the last statement in the GNU extension
-    // statement expression.
-    if (PParentStmtExpr && ParentCompStmt &&
-        ParentCompStmt->body_back() == MemberCall->getExprStmt())
-      return;
-    // Skip if it's a return statement
-    if (ParentReturnStmt)
-      return;
-
     const SourceLocation MemberLoc = MemberCall->getBeginLoc();
     const SourceLocation ReplacementLoc = MemberCall->getExprLoc();
     const SourceRange ReplacementRange =
@@ -154,13 +76,6 @@ void StandaloneEmptyCheck::check(const 
MatchFinder::MatchResult &Result) {
 
   } else if (const auto *NonMemberCall =
                  Result.Nodes.getNodeAs<CallExpr>("empty")) {
-    if (ParentCond == NonMemberCall->getExprStmt())
-      return;
-    if (PParentStmtExpr && ParentCompStmt &&
-        ParentCompStmt->body_back() == NonMemberCall->getExprStmt())
-      return;
-    if (ParentReturnStmt)
-      return;
     if (NonMemberCall->getNumArgs() != 1)
       return;
 
diff --git a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
index 7cf9696378c62..44f5ceedc6e44 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp
@@ -7,33 +7,23 @@
 
//===----------------------------------------------------------------------===//
 
 #include "ThrowKeywordMissingCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 
 using namespace clang::ast_matchers;
-using namespace clang::ast_matchers::internal;
 
 namespace clang::tidy::bugprone {
 
 void ThrowKeywordMissingCheck::registerMatchers(MatchFinder *Finder) {
-  const VariadicDynCastAllOfMatcher<Stmt, AttributedStmt> AttributedStmt;
-  // Matches an 'expression-statement', as defined in [stmt.expr]/1.
-  // Not to be confused with the similarly-named GNU extension, the
-  // statement expression.
-  const auto ExprStmt = [&](const Matcher<Expr> &InnerMatcher) {
-    return expr(hasParent(stmt(anyOf(doStmt(), whileStmt(), forStmt(),
-                                     compoundStmt(), ifStmt(), switchStmt(),
-                                     labelStmt(), AttributedStmt()))),
-                InnerMatcher);
-  };
-
   Finder->addMatcher(
-      ExprStmt(
-          cxxConstructExpr(hasType(cxxRecordDecl(anyOf(
+      cxxConstructExpr(
+          hasType(cxxRecordDecl(anyOf(
               matchesName("[Ee]xception|EXCEPTION"),
               hasAnyBase(hasType(hasCanonicalType(recordType(hasDeclaration(
                   cxxRecordDecl(matchesName("[Ee]xception|EXCEPTION"))
-                      .bind("base")))))))))))
+                      .bind("base"))))))))),
+          matchers::isDiscarded())
           .bind("temporary-exception-not-thrown"),
       this);
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
index 6502fc9bfb89e..b486a454aefe7 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
@@ -7,6 +7,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "UnusedRaiiCheck.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Lex/Lexer.h"
 
@@ -26,12 +27,13 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) 
{
   // destroyed.
   Finder->addMatcher(
       mapAnyOf(cxxConstructExpr, cxxUnresolvedConstructExpr)
-          .with(hasParent(compoundStmt().bind("compound")),
-                anyOf(hasType(hasCanonicalType(recordType(hasDeclaration(
+          .with(anyOf(hasType(hasCanonicalType(recordType(hasDeclaration(
                           cxxRecordDecl(hasNonTrivialDestructor()))))),
                       hasType(hasCanonicalType(templateSpecializationType(
                           hasDeclaration(classTemplateDecl(has(
-                              cxxRecordDecl(hasNonTrivialDestructor())))))))))
+                              cxxRecordDecl(hasNonTrivialDestructor())))))))),
+                matchers::isDiscarded(),
+                optionally(hasParent(compoundStmt().bind("compound"))))
           .bind("expr"),
       this);
 }
@@ -39,7 +41,7 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) {
 template <typename T>
 static void reportDiagnostic(const DiagnosticBuilder &D, const T *Node,
                              SourceRange SR, bool DefaultConstruction) {
-  const char *Replacement = " give_me_a_name";
+  static constexpr StringRef Replacement = " give_me_a_name";
 
   // If this is a default ctor we have to remove the parens or we'll introduce 
a
   // most vexing parse.
@@ -63,13 +65,12 @@ void UnusedRaiiCheck::check(const MatchFinder::MatchResult 
&Result) {
   if (E->getBeginLoc().isMacroID())
     return;
 
-  // Don't emit a warning for the last statement in the surrounding compound
-  // statement.
-  const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("compound");
-  const auto *LastExpr = dyn_cast<Expr>(CS->body_back());
-
-  if (LastExpr && E == LastExpr->IgnoreUnlessSpelledInSource())
-    return;
+  // Don't emit a warning if this is the last statement in a surrounding
+  // compound statement.
+  if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("compound"))
+    if (const auto *LastExpr = dyn_cast<Expr>(CS->body_back()))
+      if (E == LastExpr->IgnoreUnlessSpelledInSource())
+        return;
 
   // Emit a warning.
   auto D = diag(E->getBeginLoc(), "object destroyed immediately after "
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
index 7aee725cae434..6c9aafd02b14e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
@@ -186,32 +186,13 @@ void UnusedReturnValueCheck::registerMatchers(MatchFinder 
*Finder) {
 
   auto CheckCastToVoid =
       AllowCastToVoid ? castExpr(unless(hasCastKind(CK_ToVoid))) : castExpr();
-  auto MatchedCallExpr = expr(
-      anyOf(MatchedDirectCallExpr,
-            explicitCastExpr(unless(cxxFunctionalCastExpr()), CheckCastToVoid,
-                             hasSourceExpression(MatchedDirectCallExpr))));
-
-  auto UnusedInCompoundStmt =
-      compoundStmt(forEach(MatchedCallExpr),
-                   // The checker can't currently differentiate between the
-                   // return statement and other statements inside GNU 
statement
-                   // expressions, so disable the checker inside them to avoid
-                   // false positives.
-                   unless(hasParent(stmtExpr())));
-  auto UnusedInIfStmt =
-      ifStmt(eachOf(hasThen(MatchedCallExpr), hasElse(MatchedCallExpr)));
-  auto UnusedInWhileStmt = whileStmt(hasBody(MatchedCallExpr));
-  auto UnusedInDoStmt = doStmt(hasBody(MatchedCallExpr));
-  auto UnusedInForStmt =
-      forStmt(eachOf(hasLoopInit(MatchedCallExpr),
-                     hasIncrement(MatchedCallExpr), hasBody(MatchedCallExpr)));
-  auto UnusedInRangeForStmt = cxxForRangeStmt(hasBody(MatchedCallExpr));
-  auto UnusedInCaseStmt = switchCase(forEach(MatchedCallExpr));
 
   Finder->addMatcher(
-      stmt(anyOf(UnusedInCompoundStmt, UnusedInIfStmt, UnusedInWhileStmt,
-                 UnusedInDoStmt, UnusedInForStmt, UnusedInRangeForStmt,
-                 UnusedInCaseStmt)),
+      expr(anyOf(MatchedDirectCallExpr,
+                 explicitCastExpr(unless(cxxFunctionalCastExpr()),
+                                  CheckCastToVoid,
+                                  hasSourceExpression(MatchedDirectCallExpr))),
+           matchers::isDiscarded()),
       this);
 }
 
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
index e92155c822dc7..13efe9539c80c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp
@@ -69,51 +69,27 @@ void UseStdPrintCheck::registerPPCallbacks(const 
SourceManager &SM,
   this->PP = PP;
 }
 
-static clang::ast_matchers::StatementMatcher unusedReturnValue(
-    const clang::ast_matchers::StatementMatcher &MatchedCallExpr) {
-  auto UnusedInCompoundStmt =
-      compoundStmt(forEach(MatchedCallExpr),
-                   // The checker can't currently differentiate between the
-                   // return statement and other statements inside GNU 
statement
-                   // expressions, so disable the checker inside them to avoid
-                   // false positives.
-                   unless(hasParent(stmtExpr())));
-  auto UnusedInIfStmt =
-      ifStmt(eachOf(hasThen(MatchedCallExpr), hasElse(MatchedCallExpr)));
-  auto UnusedInWhileStmt = whileStmt(hasBody(MatchedCallExpr));
-  auto UnusedInDoStmt = doStmt(hasBody(MatchedCallExpr));
-  auto UnusedInForStmt =
-      forStmt(eachOf(hasLoopInit(MatchedCallExpr),
-                     hasIncrement(MatchedCallExpr), hasBody(MatchedCallExpr)));
-  auto UnusedInRangeForStmt = cxxForRangeStmt(hasBody(MatchedCallExpr));
-  auto UnusedInCaseStmt = switchCase(forEach(MatchedCallExpr));
-
-  return stmt(anyOf(UnusedInCompoundStmt, UnusedInIfStmt, UnusedInWhileStmt,
-                    UnusedInDoStmt, UnusedInForStmt, UnusedInRangeForStmt,
-                    UnusedInCaseStmt));
-}
-
 void UseStdPrintCheck::registerMatchers(MatchFinder *Finder) {
   if (!PrintfLikeFunctions.empty())
     Finder->addMatcher(
-        unusedReturnValue(
-            callExpr(argumentCountAtLeast(1),
-                     hasArgument(0, stringLiteral(isOrdinary())),
-                     callee(functionDecl(matchers::matchesAnyListedRegexName(
-                                             PrintfLikeFunctions))
-                                .bind("func_decl")))
-                .bind("printf")),
+        callExpr(argumentCountAtLeast(1),
+                 hasArgument(0, stringLiteral(isOrdinary())),
+                 callee(functionDecl(matchers::matchesAnyListedRegexName(
+                                         PrintfLikeFunctions))
+                            .bind("func_decl")),
+                 matchers::isDiscarded())
+            .bind("printf"),
         this);
 
   if (!FprintfLikeFunctions.empty())
     Finder->addMatcher(
-        unusedReturnValue(
-            callExpr(argumentCountAtLeast(2),
-                     hasArgument(1, stringLiteral(isOrdinary())),
-                     callee(functionDecl(matchers::matchesAnyListedRegexName(
-                                             FprintfLikeFunctions))
-                                .bind("func_decl")))
-                .bind("fprintf")),
+        callExpr(argumentCountAtLeast(2),
+                 hasArgument(1, stringLiteral(isOrdinary())),
+                 callee(functionDecl(matchers::matchesAnyListedRegexName(
+                                         FprintfLikeFunctions))
+                            .bind("func_decl")),
+                 matchers::isDiscarded())
+            .bind("fprintf"),
         this);
 }
 
diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h 
b/clang-tools-extra/clang-tidy/utils/Matchers.h
index 83401e85c8da9..b9e8adbba8dfc 100644
--- a/clang-tools-extra/clang-tidy/utils/Matchers.h
+++ b/clang-tools-extra/clang-tidy/utils/Matchers.h
@@ -10,7 +10,9 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_MATCHERS_H
 
 #include "TypeTraits.h"
+#include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/ExprConcepts.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include <optional>
 
@@ -74,6 +76,61 @@ AST_MATCHER(Expr, hasUnevaluatedContext) {
   return false;
 }
 
+AST_MATCHER(Expr, isDiscarded) {
+  const DynTypedNodeList Parents = [&] {
+    const TraversalKindScope _(Finder->getASTContext(),
+                               TK_IgnoreUnlessSpelledInSource);
+    return Finder->getASTContext().getParents(Node);
+  }();
+  if (Parents.size() != 1)
+    return false;
+  const DynTypedNode Parent = Parents[0];
+
+  const Expr *const DesiredNode = Node.IgnoreUnlessSpelledInSource();
+  const auto IsCurrentNode = [&](const Stmt *S) {
+    const auto *const AsExpr = dyn_cast_if_present<Expr>(S);
+    return AsExpr && AsExpr->IgnoreUnlessSpelledInSource() == DesiredNode;
+  };
+
+  if (const auto *While = Parent.get<WhileStmt>())
+    return IsCurrentNode(While->getBody());
+
+  if (const auto *For = Parent.get<ForStmt>())
+    return IsCurrentNode(For->getBody()) || IsCurrentNode(For->getInit()) ||
+           IsCurrentNode(For->getInc());
+
+  if (const auto *Do = Parent.get<DoStmt>())
+    return IsCurrentNode(Do->getBody());
+
+  if (const auto *If = Parent.get<IfStmt>())
+    return IsCurrentNode(If->getThen()) || IsCurrentNode(If->getElse());
+
+  if (const auto *ForRange = Parent.get<CXXForRangeStmt>())
+    return IsCurrentNode(ForRange->getBody());
+
+  if (const auto *Switch = Parent.get<SwitchStmt>())
+    return IsCurrentNode(Switch->getBody());
+
+  if (const auto *Case = Parent.get<SwitchCase>())
+    return true;
+
+  if (const auto *Label = Parent.get<LabelStmt>())
+    return true;
+
+  if (const auto *AttrStmt = Parent.get<AttributedStmt>())
+    return true;
+
+  if (const auto *Compound = Parent.get<CompoundStmt>()) {
+    // Is this statement the return value of a GNU statement expression?
+    const DynTypedNodeList Grandparents =
+        Finder->getASTContext().getParents(Parent);
+    return !(Grandparents.size() == 1 && Grandparents[0].get<StmtExpr>() &&
+             IsCurrentNode(Compound->body_back()));
+  }
+
+  return false;
+}
+
 // A matcher implementation that matches a list of type name regular 
expressions
 // against a NamedDecl. If a regular expression contains the substring "::"
 // matching will occur against the qualified name, otherwise only the typename.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
index 63972cc0fd25e..e202a9d194113 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp
@@ -184,6 +184,11 @@ int printf_uses_return_value(int choice) {
   // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 
'printf' [modernize-use-std-print]
   // CHECK-FIXES-NOT: std::println("GCC statement expression with unused 
result {}", i);
 
+label:
+  printf("Label target %d\n", i);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 
'printf' [modernize-use-std-print]
+  // CHECK-FIXES: std::println("Label target {}", i);
+
   return printf("Return value used in return\n");
 }
 

>From 768fe17d9005b644d82d036de565bf3057fb8f29 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Sun, 1 Mar 2026 22:58:52 -0800
Subject: [PATCH 2/3] Turn slight slowdown into a speedup in
 `bugprone-unused-return-value`

---
 .../clang-tidy/bugprone/UnusedReturnValueCheck.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
index 6c9aafd02b14e..334d901b0a423 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
@@ -171,7 +171,7 @@ void 
UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 }
 
 void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
-  auto MatchedDirectCallExpr = expr(
+  auto MatchedDirectCallExpr =
       callExpr(callee(functionDecl(
                    // Don't match copy or move assignment operator.
                    unless(isAssignmentOverloadedOperator()),
@@ -182,17 +182,17 @@ void UnusedReturnValueCheck::registerMatchers(MatchFinder 
*Finder) {
                          returns(hasCanonicalType(hasDeclaration(
                              namedDecl(matchers::matchesAnyListedRegexName(
                                  CheckedReturnTypes)))))))))
-          .bind("match"));
+          .bind("match");
 
   auto CheckCastToVoid =
       AllowCastToVoid ? castExpr(unless(hasCastKind(CK_ToVoid))) : castExpr();
 
+  Finder->addMatcher(callExpr(MatchedDirectCallExpr, matchers::isDiscarded()),
+                     this);
   Finder->addMatcher(
-      expr(anyOf(MatchedDirectCallExpr,
-                 explicitCastExpr(unless(cxxFunctionalCastExpr()),
-                                  CheckCastToVoid,
-                                  hasSourceExpression(MatchedDirectCallExpr))),
-           matchers::isDiscarded()),
+      explicitCastExpr(unless(cxxFunctionalCastExpr()), CheckCastToVoid,
+                       hasSourceExpression(MatchedDirectCallExpr),
+                       matchers::isDiscarded()),
       this);
 }
 

>From c511854426e9190ea2f1b285a681f941146547ea Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <[email protected]>
Date: Sun, 1 Mar 2026 23:08:07 -0800
Subject: [PATCH 3/3] Remove unused locals

---
 clang-tools-extra/clang-tidy/utils/Matchers.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.h 
b/clang-tools-extra/clang-tidy/utils/Matchers.h
index b9e8adbba8dfc..e3b7d612bc63c 100644
--- a/clang-tools-extra/clang-tidy/utils/Matchers.h
+++ b/clang-tools-extra/clang-tidy/utils/Matchers.h
@@ -111,13 +111,13 @@ AST_MATCHER(Expr, isDiscarded) {
   if (const auto *Switch = Parent.get<SwitchStmt>())
     return IsCurrentNode(Switch->getBody());
 
-  if (const auto *Case = Parent.get<SwitchCase>())
+  if (Parent.get<SwitchCase>())
     return true;
 
-  if (const auto *Label = Parent.get<LabelStmt>())
+  if (Parent.get<LabelStmt>())
     return true;
 
-  if (const auto *AttrStmt = Parent.get<AttributedStmt>())
+  if (Parent.get<AttributedStmt>())
     return true;
 
   if (const auto *Compound = Parent.get<CompoundStmt>()) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to