https://github.com/moar55 updated 
https://github.com/llvm/llvm-project/pull/193407

>From 85bbb13ef79566f31c6784b2a3dbe613847049d6 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Wed, 22 Apr 2026 06:48:56 +0200
Subject: [PATCH 01/11] Replace iterator version of erase-remove idiom with
 std::erase and std::erase_if

---
 .../clang-tidy/modernize/CMakeLists.txt       |   1 +
 .../modernize/ModernizeTidyModule.cpp         |   2 +
 .../clang-tidy/modernize/UseStdEraseCheck.cpp | 125 ++++++++++++++++++
 .../clang-tidy/modernize/UseStdEraseCheck.h   |  35 +++++
 clang-tools-extra/docs/ReleaseNotes.rst       |   5 +
 .../docs/clang-tidy/checks/list.rst           |   1 +
 .../checks/modernize/use-std-erase.rst        |  16 +++
 .../checkers/modernize/use-std-erase.cpp      | 122 +++++++++++++++++
 8 files changed, 307 insertions(+)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 2c5c44db587fe..45cf3d1c7ad92 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -12,6 +12,7 @@ add_clang_library(clangTidyModernizeModule STATIC
   ConcatNestedNamespacesCheck.cpp
   DeprecatedHeadersCheck.cpp
   DeprecatedIosBaseAliasesCheck.cpp
+  UseStdEraseCheck.cpp
   IntegralLiteralExpressionMatcher.cpp
   LoopConvertCheck.cpp
   LoopConvertUtils.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index cc13da7535bcb..abd2f11a44e48 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -16,6 +16,7 @@
 #include "ConcatNestedNamespacesCheck.h"
 #include "DeprecatedHeadersCheck.h"
 #include "DeprecatedIosBaseAliasesCheck.h"
+#include "UseStdEraseCheck.h"
 #include "LoopConvertCheck.h"
 #include "MacroToEnumCheck.h"
 #include "MakeSharedCheck.h"
@@ -81,6 +82,7 @@ class ModernizeModule : public ClangTidyModule {
         "modernize-deprecated-headers");
     CheckFactories.registerCheck<DeprecatedIosBaseAliasesCheck>(
         "modernize-deprecated-ios-base-aliases");
+    CheckFactories.registerCheck<UseStdEraseCheck>("modernize-use-std-erase");
     CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert");
     CheckFactories.registerCheck<MacroToEnumCheck>("modernize-macro-to-enum");
     CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
new file mode 100644
index 0000000000000..6e2b73054561e
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseStdEraseCheck.h"
+#include "../utils/Matchers.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringRef.h"
+#include <initializer_list>
+#include <string_view>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+namespace {
+
+constexpr std::array<llvm::StringRef, 2> EraseEndMethodNames = {"end", "cend"};
+constexpr std::array<llvm::StringRef, 2> EraseEndFreeNames = {"end", "cend"};
+constexpr const char *EraseThis = "EraseThis";
+
+AST_MATCHER(Expr, hasSideEffects) {
+  return Node.HasSideEffects(Finder->getASTContext());
+}
+
+auto makeExprMatcher(
+    const ast_matchers::internal::Matcher<Expr> &ArgumentMatcher,
+    ArrayRef<StringRef> MethodNames, ArrayRef<StringRef> FreeNames) {
+  return expr(
+      anyOf(cxxMemberCallExpr(argumentCountIs(0),
+                              callee(cxxMethodDecl(hasAnyName(MethodNames))),
+                              on(ArgumentMatcher)),
+            callExpr(argumentCountIs(1), hasArgument(0, ArgumentMatcher),
+                     hasDeclaration(functionDecl(hasAnyName(FreeNames))))));
+}
+
+ast_matchers::internal::Matcher<Expr> makeMatcherPair() {
+  ast_matchers::internal::Matcher<CallExpr> ArgumentMatcher = allOf(
+      hasArgument(
+          0, makeExprMatcher(expr(unless(hasSideEffects())).bind(EraseThis),
+                             {"begin"}, {"::std::begin"})),
+      hasArgument(
+          1, makeExprMatcher(
+                 expr(matchers::isStatementIdenticalToBoundNode(EraseThis)),
+                 {"end"}, {"::std::end"})),
+      hasArgument(2, expr().bind("valueOrCond")));
+
+  return callExpr(callee(functionDecl(hasAnyName("remove", "remove_if"))),
+                  argumentCountIs(3), ArgumentMatcher)
+      .bind("remove");
+}
+
+} // namespace
+
+void UseStdEraseCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsCpp20EraseContainer = cxxRecordDecl(
+      hasAnyName("vector", "deque", "list", "forward_list", "basic_string"),
+      isInStdNamespace());
+
+  const auto EraseableContainerType = type(hasUnqualifiedDesugaredType(
+      tagType(hasDeclaration(IsCpp20EraseContainer))));
+
+  auto EraseEndCheck = makeExprMatcher(
+      expr(matchers::isStatementIdenticalToBoundNode(EraseThis)),
+      EraseEndMethodNames, EraseEndFreeNames);
+
+  Finder->addMatcher(
+      cxxMemberCallExpr(callee(cxxMethodDecl(hasName("erase"))),
+                        hasArgument(0, makeMatcherPair()),
+                        hasArgument(1, EraseEndCheck),
+                        on(anyOf(hasType(EraseableContainerType),
+                                 hasType(pointsTo(EraseableContainerType)))))
+          .bind("erase"),
+      this);
+}
+
+void UseStdEraseCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *EraseCall = Result.Nodes.getNodeAs<CXXMemberCallExpr>("erase");
+  const auto *RemoveCall = Result.Nodes.getNodeAs<CallExpr>("remove");
+  const auto *ContainerThis = Result.Nodes.getNodeAs<Expr>(EraseThis);
+  const auto *ValueOrCond = Result.Nodes.getNodeAs<Expr>("valueOrCond");
+
+  if (!EraseCall || !RemoveCall || !ContainerThis || !ValueOrCond)
+    return;
+
+  const CXXMethodDecl *EraseMethod = EraseCall->getMethodDecl();
+  if (!EraseMethod)
+    return;
+
+  const std::string RemoveFuncName =
+      RemoveCall->getDirectCallee()->getName().str();
+
+  const std::string ReplacementFreeFunc =
+      RemoveFuncName == "remove" ? "std::erase" : "std::erase_if";
+
+  std::string Replacement =
+      ReplacementFreeFunc + "(" +
+      Lexer::getSourceText(
+          CharSourceRange::getTokenRange(ContainerThis->getSourceRange()),
+          Result.Context->getSourceManager(), Result.Context->getLangOpts())
+          .str() +
+      ", " +
+      Lexer::getSourceText(
+          CharSourceRange::getTokenRange(ValueOrCond->getSourceRange()),
+          Result.Context->getSourceManager(), Result.Context->getLangOpts())
+          .str() +
+      ")";
+
+  diag(EraseCall->getExprLoc(),
+       "prefer %0 over the erase-" + RemoveFuncName + " idiom")
+      << ReplacementFreeFunc
+      << FixItHint::CreateReplacement(EraseCall->getSourceRange(), 
Replacement);
+}
+
+} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.h
new file mode 100644
index 0000000000000..6a5023533ff89
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDERASECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDERASECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::modernize {
+
+/// Replace erase-remove idiom with C++20's std::erase and std::erase_if for
+/// improved readability.
+///
+class UseStdEraseCheck : public ClangTidyCheck {
+public:
+  UseStdEraseCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus20;
+  }
+  std::optional<TraversalKind> getCheckTraversalKind() const override {
+    return TK_IgnoreUnlessSpelledInSource;
+  }
+};
+
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDERASECHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index f70bf9e9f9eb8..19eaf9faa3ab2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,6 +145,11 @@ New checks
   ``llvm::to_vector(llvm::make_filter_range(...))`` that can be replaced with
   ``llvm::map_to_vector`` and ``llvm::filter_to_vector``.
 
+- New :doc:`modernize-use-std-erase
+  <clang-tidy/checks/modernize/use-std-erase>` check.
+
+  Replaces erase-remove idiom with C++20's' std::erase and std::erase_if for 
improved readability.
+
 - New :doc:`modernize-use-std-bit
   <clang-tidy/checks/modernize/use-std-bit>` check.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst 
b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 053ce6f0779d9..8571f8b7b0e20 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -327,6 +327,7 @@ Clang-Tidy Checks
    :doc:`modernize-use-scoped-lock <modernize/use-scoped-lock>`, "Yes"
    :doc:`modernize-use-starts-ends-with <modernize/use-starts-ends-with>`, 
"Yes"
    :doc:`modernize-use-std-bit <modernize/use-std-bit>`, "Yes"
+   :doc:`modernize-use-std-erase <modernize/use-std-erase>`, "Yes"
    :doc:`modernize-use-std-format <modernize/use-std-format>`, "Yes"
    :doc:`modernize-use-std-numbers <modernize/use-std-numbers>`, "Yes"
    :doc:`modernize-use-std-print <modernize/use-std-print>`, "Yes"
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
new file mode 100644
index 0000000000000..9bd3fb26035de
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - modernize-use-std-erase
+
+modernize-use-std-erase
+=======================
+
+Replaces erase-remove idiom with C++20's' std::erase and std::erase_if 
+for improved readability.
+
+Covered scenarios:
+
+========================================================== 
============================
+Expression                                                 Replacement
+---------------------------------------------------------- 
----------------------------
+``v.erase(std::remove(v.begin(), v.end(), 5), v.end())``   ``std::erase(v, 5)``
+``l.erase(std::remove_if(v.begin(), v.end(), 5), isEven)`` ``std::erase_if(v, 
isEven)``
+========================================================== 
============================
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp
new file mode 100644
index 0000000000000..afce0c1c9d243
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp
@@ -0,0 +1,122 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-erase %t
+
+namespace std {
+
+template <typename T>
+struct vector {
+  using iterator = T*;
+  using reverse_iterator = T*;
+  iterator begin();
+  iterator end();
+  reverse_iterator rbegin();
+  reverse_iterator rend();
+  iterator erase(iterator, iterator);
+};
+
+template <typename T>
+struct deque {
+  using iterator = T*;
+  iterator begin();
+  iterator end();
+  iterator erase(iterator, iterator);
+};
+
+template <typename T>
+struct list {
+  using iterator = T*;
+  iterator begin();
+  iterator end();
+  iterator erase(iterator, iterator);
+};
+
+template <typename T>
+struct basic_string {
+  using iterator = T*;
+  iterator begin();
+  iterator end();
+  iterator erase(iterator, iterator);
+};
+using string = basic_string<char>;
+
+template <class ForwardIt, class T>
+ForwardIt remove(ForwardIt first, ForwardIt last, const T& value);
+
+template <class ForwardIt, class UnaryPredicate>
+ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p);
+
+// Dummy implementation
+template <class ForwardIt, class UnaryPredicate>
+ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p) {
+  return first;
+}
+
+} // namespace std
+
+// Custom container - should be ignored
+template <typename T>
+struct MyContainer {
+  using iterator = T*;
+  iterator begin();
+  iterator end();
+  iterator erase(iterator, iterator);
+};
+
+void test_standard_remove_idiom() {
+  std::vector<int> v;
+  v.erase(std::remove(v.begin(), v.end(), 42), v.end());
+  // CHECK-MESSAGES: {{.*}}: warning: prefer std::erase over the erase-remove 
idiom [modernize-use-std-erase]
+  // CHECK-FIXES: std::erase(v, 42);
+
+  std::deque<int> d;
+  d.erase(std::remove(d.begin(), d.end(), 42), d.end());
+  // CHECK-MESSAGES: {{.*}}: warning: prefer std::erase over the erase-remove 
idiom [modernize-use-std-erase]
+  // CHECK-FIXES: std::erase(d, 42);
+}
+
+void test_standard_remove_if_idiom() {
+  std::vector<int> v;
+  auto IsNegative = [](int x) { return x < 0; };
+  
+  v.erase(std::remove_if(v.begin(), v.end(), IsNegative), v.end());
+  // CHECK-MESSAGES: {{.*}}: warning: prefer std::erase_if over the 
erase-remove_if idiom [modernize-use-std-erase]
+  // CHECK-FIXES: std::erase_if(v, IsNegative);
+
+  std::list<int> l;
+  l.erase(std::remove_if(l.begin(), l.end(), IsNegative), l.end());
+  // CHECK-MESSAGES: {{.*}}: warning: prefer std::erase_if over the 
erase-remove_if idiom [modernize-use-std-erase]
+  // CHECK-FIXES: std::erase_if(l, IsNegative);
+}
+
+void test_string_special_case() {
+  std::string s;
+  s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
+  // CHECK-MESSAGES: {{.*}}: warning: prefer std::erase over the erase-remove 
idiom [modernize-use-std-erase]
+  // CHECK-FIXES: std::erase(s, ' ');
+}
+
+auto IsEven = [](int i) { return i % 2 == 0; };
+
+void test_remove_negative_cases() {
+  std::vector<int> v;
+  std::vector<int> v2;
+
+  v.erase(std::remove_if(v.rbegin(), v.rend(), IsEven), v.rend());
+  // CHECK-FIXES: v.erase(std::remove_if(v.rbegin(), v.rend(), IsEven), 
v.rend());
+
+  MyContainer<int> c;
+  c.erase(std::remove_if(c.begin(), c.end(), IsEven), c.end());
+  // CHECK-FIXES: c.erase(std::remove_if(c.begin(), c.end(), IsEven), c.end());
+
+  v.erase(std::remove_if(v.begin() + 1, v.end(), IsEven), v.end());
+  // CHECK-FIXES: v.erase(std::remove_if(v.begin() + 1, v.end(), IsEven), 
v.end());
+  //
+  v.erase(std::remove(v2.begin(), v2.end(), 1), v.end());
+  // CHECK-FIXES: v.erase(std::remove(v2.begin(), v2.end(), 1), v.end());
+
+  v.erase(std::remove(v.begin(), v.end(), 1), v.end() - 1);
+  // CHECK-FIXES: v.erase(std::remove(v.begin(), v.end(), 1), v.end() - 1);
+
+  auto it = std::remove(v.begin(), v.end(), 1);
+  v.erase(it, v.end());
+  // CHECK-FIXES: v.erase(it, v.end());
+}

>From 9fea68f83501d07d8cded27d30fd6eb6fecb7f7d Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Wed, 22 Apr 2026 07:19:11 +0200
Subject: [PATCH 02/11] clang-format

---
 clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index abd2f11a44e48..28493994eb775 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -16,7 +16,6 @@
 #include "ConcatNestedNamespacesCheck.h"
 #include "DeprecatedHeadersCheck.h"
 #include "DeprecatedIosBaseAliasesCheck.h"
-#include "UseStdEraseCheck.h"
 #include "LoopConvertCheck.h"
 #include "MacroToEnumCheck.h"
 #include "MakeSharedCheck.h"
@@ -49,6 +48,7 @@
 #include "UseScopedLockCheck.h"
 #include "UseStartsEndsWithCheck.h"
 #include "UseStdBitCheck.h"
+#include "UseStdEraseCheck.h"
 #include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"

>From 182ee62f81355bfe1564a100c5defca5a7796ca3 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Wed, 22 Apr 2026 07:28:24 +0200
Subject: [PATCH 03/11] make matcher stricter, remove unused include, adjust
 unsorted release note

---
 clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index 6e2b73054561e..4a6d2b8fef46c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -17,7 +17,6 @@
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringRef.h"
 #include <initializer_list>
-#include <string_view>
 
 using namespace clang::ast_matchers;
 
@@ -76,7 +75,7 @@ void UseStdEraseCheck::registerMatchers(MatchFinder *Finder) {
 
   Finder->addMatcher(
       cxxMemberCallExpr(callee(cxxMethodDecl(hasName("erase"))),
-                        hasArgument(0, makeMatcherPair()),
+                        argumentCountIs(2), hasArgument(0, makeMatcherPair()),
                         hasArgument(1, EraseEndCheck),
                         on(anyOf(hasType(EraseableContainerType),
                                  hasType(pointsTo(EraseableContainerType)))))

>From 8333c01c10d817872d9c748a9984d99d6c3e79df Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Sun, 26 Apr 2026 11:03:03 +0200
Subject: [PATCH 04/11] address comments

---
 .../clang-tidy/modernize/CMakeLists.txt       |  2 +-
 .../modernize/ModernizeTidyModule.cpp         |  2 +-
 .../clang-tidy/modernize/UseStdEraseCheck.cpp | 28 ++++++------
 clang-tools-extra/docs/ReleaseNotes.rst       |  2 +-
 .../checks/modernize/use-std-erase.rst        |  2 +-
 .../checkers/modernize/use-std-erase.cpp      | 43 +++----------------
 6 files changed, 22 insertions(+), 57 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 45cf3d1c7ad92..6abfc38f413c6 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -12,7 +12,6 @@ add_clang_library(clangTidyModernizeModule STATIC
   ConcatNestedNamespacesCheck.cpp
   DeprecatedHeadersCheck.cpp
   DeprecatedIosBaseAliasesCheck.cpp
-  UseStdEraseCheck.cpp
   IntegralLiteralExpressionMatcher.cpp
   LoopConvertCheck.cpp
   LoopConvertUtils.cpp
@@ -49,6 +48,7 @@ add_clang_library(clangTidyModernizeModule STATIC
   UseScopedLockCheck.cpp
   UseStartsEndsWithCheck.cpp
   UseStdBitCheck.cpp
+  UseStdEraseCheck.cpp
   UseStdFormatCheck.cpp
   UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 28493994eb775..001f91f6f7337 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -82,7 +82,6 @@ class ModernizeModule : public ClangTidyModule {
         "modernize-deprecated-headers");
     CheckFactories.registerCheck<DeprecatedIosBaseAliasesCheck>(
         "modernize-deprecated-ios-base-aliases");
-    CheckFactories.registerCheck<UseStdEraseCheck>("modernize-use-std-erase");
     CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert");
     CheckFactories.registerCheck<MacroToEnumCheck>("modernize-macro-to-enum");
     CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared");
@@ -100,6 +99,7 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<UseStartsEndsWithCheck>(
         "modernize-use-starts-ends-with");
     CheckFactories.registerCheck<UseStdBitCheck>("modernize-use-std-bit");
+    CheckFactories.registerCheck<UseStdEraseCheck>("modernize-use-std-erase");
     
CheckFactories.registerCheck<UseStdFormatCheck>("modernize-use-std-format");
     CheckFactories.registerCheck<UseStdNumbersCheck>(
         "modernize-use-std-numbers");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index 4a6d2b8fef46c..7349bd932e83f 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -96,27 +96,25 @@ void UseStdEraseCheck::check(const MatchFinder::MatchResult 
&Result) {
   if (!EraseMethod)
     return;
 
-  const std::string RemoveFuncName =
-      RemoveCall->getDirectCallee()->getName().str();
+  const StringRef RemoveFuncName = RemoveCall->getDirectCallee()->getName();
 
-  const std::string ReplacementFreeFunc =
+  const StringRef ReplacementFreeFunc =
       RemoveFuncName == "remove" ? "std::erase" : "std::erase_if";
 
   std::string Replacement =
-      ReplacementFreeFunc + "(" +
-      Lexer::getSourceText(
-          CharSourceRange::getTokenRange(ContainerThis->getSourceRange()),
-          Result.Context->getSourceManager(), Result.Context->getLangOpts())
-          .str() +
-      ", " +
-      Lexer::getSourceText(
-          CharSourceRange::getTokenRange(ValueOrCond->getSourceRange()),
-          Result.Context->getSourceManager(), Result.Context->getLangOpts())
-          .str() +
-      ")";
+      (ReplacementFreeFunc + "(" +
+       Lexer::getSourceText(
+           CharSourceRange::getTokenRange(ContainerThis->getSourceRange()),
+           Result.Context->getSourceManager(), Result.Context->getLangOpts()) +
+       ", " +
+       Lexer::getSourceText(
+           CharSourceRange::getTokenRange(ValueOrCond->getSourceRange()),
+           Result.Context->getSourceManager(), Result.Context->getLangOpts()) +
+       ")")
+          .str();
 
   diag(EraseCall->getExprLoc(),
-       "prefer %0 over the erase-" + RemoveFuncName + " idiom")
+       ("prefer %0 over the erase-" + RemoveFuncName + " idiom").str())
       << ReplacementFreeFunc
       << FixItHint::CreateReplacement(EraseCall->getSourceRange(), 
Replacement);
 }
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 5b44dc1aad17f..fa3b5701e95b4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -244,7 +244,7 @@ New checks
 - New :doc:`modernize-use-std-erase
   <clang-tidy/checks/modernize/use-std-erase>` check.
 
-  Replaces erase-remove idiom with C++20's' std::erase and std::erase_if for 
improved readability.
+  Replaces erase-remove idiom with C++20's' `std::erase` and `std::erase_if` 
for improved readability.
 
 - New :doc:`modernize-use-string-view
   <clang-tidy/checks/modernize/use-string-view>` check.
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
index 9bd3fb26035de..99184e8126c57 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
@@ -3,7 +3,7 @@
 modernize-use-std-erase
 =======================
 
-Replaces erase-remove idiom with C++20's' std::erase and std::erase_if 
+Replaces erase-remove idiom with C++20's' `std::erase` and `std::erase_if`
 for improved readability.
 
 Covered scenarios:
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp
index afce0c1c9d243..0839bfcb87b0f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-erase.cpp
@@ -1,43 +1,10 @@
 // RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-erase %t
+#include <deque>
+#include <list>
+#include <string>
+#include <vector>
 
 namespace std {
-
-template <typename T>
-struct vector {
-  using iterator = T*;
-  using reverse_iterator = T*;
-  iterator begin();
-  iterator end();
-  reverse_iterator rbegin();
-  reverse_iterator rend();
-  iterator erase(iterator, iterator);
-};
-
-template <typename T>
-struct deque {
-  using iterator = T*;
-  iterator begin();
-  iterator end();
-  iterator erase(iterator, iterator);
-};
-
-template <typename T>
-struct list {
-  using iterator = T*;
-  iterator begin();
-  iterator end();
-  iterator erase(iterator, iterator);
-};
-
-template <typename T>
-struct basic_string {
-  using iterator = T*;
-  iterator begin();
-  iterator end();
-  iterator erase(iterator, iterator);
-};
-using string = basic_string<char>;
-
 template <class ForwardIt, class T>
 ForwardIt remove(ForwardIt first, ForwardIt last, const T& value);
 
@@ -109,7 +76,7 @@ void test_remove_negative_cases() {
 
   v.erase(std::remove_if(v.begin() + 1, v.end(), IsEven), v.end());
   // CHECK-FIXES: v.erase(std::remove_if(v.begin() + 1, v.end(), IsEven), 
v.end());
-  //
+ 
   v.erase(std::remove(v2.begin(), v2.end(), 1), v.end());
   // CHECK-FIXES: v.erase(std::remove(v2.begin(), v2.end(), 1), v.end());
 

>From e0f74ade0e036fa0a6bf56d4111605b4cc08cf5e Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Sun, 26 Apr 2026 11:09:41 +0200
Subject: [PATCH 05/11] fix issues in docs/release notes

---
 clang-tools-extra/docs/ReleaseNotes.rst            |  2 +-
 .../clang-tidy/checks/modernize/use-std-erase.rst  | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index fa3b5701e95b4..4aec752e56375 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -244,7 +244,7 @@ New checks
 - New :doc:`modernize-use-std-erase
   <clang-tidy/checks/modernize/use-std-erase>` check.
 
-  Replaces erase-remove idiom with C++20's' `std::erase` and `std::erase_if` 
for improved readability.
+  Replaces erase-remove idiom with C++20's `std::erase` and `std::erase_if` 
for improved readability.
 
 - New :doc:`modernize-use-string-view
   <clang-tidy/checks/modernize/use-string-view>` check.
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
index 99184e8126c57..b0a1f26bdb45b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
@@ -3,14 +3,14 @@
 modernize-use-std-erase
 =======================
 
-Replaces erase-remove idiom with C++20's' `std::erase` and `std::erase_if`
+Replaces erase-remove idiom with C++20's `std::erase` and `std::erase_if`
 for improved readability.
 
 Covered scenarios:
 
-========================================================== 
============================
-Expression                                                 Replacement
----------------------------------------------------------- 
----------------------------
-``v.erase(std::remove(v.begin(), v.end(), 5), v.end())``   ``std::erase(v, 5)``
-``l.erase(std::remove_if(v.begin(), v.end(), 5), isEven)`` ``std::erase_if(v, 
isEven)``
-========================================================== 
============================
+================================================================ 
============================
+Expression                                                       Replacement
+---------------------------------------------------------------- 
----------------------------
+``v.erase(std::remove(v.begin(), v.end(), 5), v.end())``         
``std::erase(v, 5)``
+``l.erase(std::remove_if(l.begin(), l.end(), isEven), l.end())`` 
``std::erase_if(l, isEven)``
+================================================================ 
============================

>From 751b9d27ea0e11ba178e8f8169d4768d3ee9b04a Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Tue, 12 May 2026 22:19:30 +0200
Subject: [PATCH 06/11] address comments

---
 .../clang-tidy/modernize/UseStdEraseCheck.cpp | 44 ++++++++++---------
 .../checkers/Inputs/Headers/std/deque         | 14 ++++++
 .../checkers/Inputs/Headers/std/list          | 10 +++++
 .../checkers/Inputs/Headers/std/string        | 31 +++++++++++++
 4 files changed, 78 insertions(+), 21 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index 7349bd932e83f..dec4885a86231 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -16,25 +16,28 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include <cassert>
 #include <initializer_list>
 
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
 
-namespace {
-
 constexpr std::array<llvm::StringRef, 2> EraseEndMethodNames = {"end", "cend"};
 constexpr std::array<llvm::StringRef, 2> EraseEndFreeNames = {"end", "cend"};
-constexpr const char *EraseThis = "EraseThis";
+constexpr const llvm::StringRef EraseThis = "EraseThis";
 
+namespace {
 AST_MATCHER(Expr, hasSideEffects) {
   return Node.HasSideEffects(Finder->getASTContext());
 }
+} // namespace
 
-auto makeExprMatcher(
-    const ast_matchers::internal::Matcher<Expr> &ArgumentMatcher,
-    ArrayRef<StringRef> MethodNames, ArrayRef<StringRef> FreeNames) {
+static auto
+makeExprMatcher(const ast_matchers::internal::Matcher<Expr> &ArgumentMatcher,
+                ArrayRef<StringRef> MethodNames,
+                ArrayRef<StringRef> FreeNames) {
   return expr(
       anyOf(cxxMemberCallExpr(argumentCountIs(0),
                               callee(cxxMethodDecl(hasAnyName(MethodNames))),
@@ -43,15 +46,15 @@ auto makeExprMatcher(
                      hasDeclaration(functionDecl(hasAnyName(FreeNames))))));
 }
 
-ast_matchers::internal::Matcher<Expr> makeMatcherPair() {
+static ast_matchers::internal::Matcher<Expr> makeMatcherPair() {
   ast_matchers::internal::Matcher<CallExpr> ArgumentMatcher = allOf(
       hasArgument(
           0, makeExprMatcher(expr(unless(hasSideEffects())).bind(EraseThis),
                              {"begin"}, {"::std::begin"})),
       hasArgument(
-          1, makeExprMatcher(
-                 expr(matchers::isStatementIdenticalToBoundNode(EraseThis)),
-                 {"end"}, {"::std::end"})),
+          1, makeExprMatcher(expr(matchers::isStatementIdenticalToBoundNode(
+                                 EraseThis.str())),
+                             {"end"}, {"::std::end"})),
       hasArgument(2, expr().bind("valueOrCond")));
 
   return callExpr(callee(functionDecl(hasAnyName("remove", "remove_if"))),
@@ -59,8 +62,6 @@ ast_matchers::internal::Matcher<Expr> makeMatcherPair() {
       .bind("remove");
 }
 
-} // namespace
-
 void UseStdEraseCheck::registerMatchers(MatchFinder *Finder) {
   const auto IsCpp20EraseContainer = cxxRecordDecl(
       hasAnyName("vector", "deque", "list", "forward_list", "basic_string"),
@@ -70,7 +71,7 @@ void UseStdEraseCheck::registerMatchers(MatchFinder *Finder) {
       tagType(hasDeclaration(IsCpp20EraseContainer))));
 
   auto EraseEndCheck = makeExprMatcher(
-      expr(matchers::isStatementIdenticalToBoundNode(EraseThis)),
+      expr(matchers::isStatementIdenticalToBoundNode(EraseThis.str())),
       EraseEndMethodNames, EraseEndFreeNames);
 
   Finder->addMatcher(
@@ -93,8 +94,7 @@ void UseStdEraseCheck::check(const MatchFinder::MatchResult 
&Result) {
     return;
 
   const CXXMethodDecl *EraseMethod = EraseCall->getMethodDecl();
-  if (!EraseMethod)
-    return;
+  assert(EraseMethod);
 
   const StringRef RemoveFuncName = RemoveCall->getDirectCallee()->getName();
 
@@ -102,7 +102,7 @@ void UseStdEraseCheck::check(const MatchFinder::MatchResult 
&Result) {
       RemoveFuncName == "remove" ? "std::erase" : "std::erase_if";
 
   std::string Replacement =
-      (ReplacementFreeFunc + "(" +
+      (ReplacementFreeFunc + llvm::Twine{"("} +
        Lexer::getSourceText(
            CharSourceRange::getTokenRange(ContainerThis->getSourceRange()),
            Result.Context->getSourceManager(), Result.Context->getLangOpts()) +
@@ -110,13 +110,15 @@ void UseStdEraseCheck::check(const 
MatchFinder::MatchResult &Result) {
        Lexer::getSourceText(
            CharSourceRange::getTokenRange(ValueOrCond->getSourceRange()),
            Result.Context->getSourceManager(), Result.Context->getLangOpts()) +
-       ")")
+       llvm::Twine{")"})
           .str();
 
-  diag(EraseCall->getExprLoc(),
-       ("prefer %0 over the erase-" + RemoveFuncName + " idiom").str())
-      << ReplacementFreeFunc
-      << FixItHint::CreateReplacement(EraseCall->getSourceRange(), 
Replacement);
+  DiagnosticBuilder Diag =
+      diag(EraseCall->getExprLoc(), "prefer %0 over the erase-%1 idiom")
+      << ReplacementFreeFunc << RemoveFuncName;
+
+  Diag << FixItHint::CreateReplacement(EraseCall->getSourceRange(),
+                                       Replacement);
 }
 
 } // namespace clang::tidy::modernize
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/deque 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/deque
index 9f7393b467321..503beb39321ca 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/deque
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/deque
@@ -54,6 +54,20 @@ public:
   template <typename... Args>
   void emplace_front(Args &&...args) {}
 
+
+  iterator insert(const_iterator p, const value_type& v);
+  iterator insert(const_iterator p, value_type&& v);
+  iterator insert(const_iterator p, size_t n, const value_type& v);
+  template <class InputIterator>
+      iterator insert(const_iterator p, InputIterator f, InputIterator l);
+  iterator insert(const_iterator p, initializer_list<value_type> il);
+
+  void pop_front();
+  void pop_back();
+
+  iterator erase(const_iterator p);
+  iterator erase(const_iterator f, const_iterator l);
+
   T &operator[](size_t);
   const T &operator[](size_t) const;
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/list 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/list
index a5ea99180869a..f02bdfd1f2bf5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/list
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/list
@@ -54,6 +54,16 @@ public:
   template <typename... Args>
   void emplace_front(Args &&...args) {}
 
+  iterator insert(const_iterator position, const value_type& x);
+  iterator insert(const_iterator position, value_type&& x);
+  iterator insert(const_iterator position, size_t n, const value_type& x);
+  template <class Iter>
+      iterator insert(const_iterator position, Iter first, Iter last);
+  iterator insert(const_iterator position, initializer_list<value_type> il);
+
+  iterator erase(const_iterator position);
+  iterator erase(const_iterator position, const_iterator last);
+
   void assign(size_t count, const T &value);
 
   void clear();
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/string 
b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/string
index dbebeaaa46514..048582fe6ec97 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/string
+++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/std/string
@@ -28,6 +28,29 @@ struct basic_string {
   basic_string(size_t, C);
   operator basic_string_view<C, T>() const;
 
+  class iterator {
+  public:
+    iterator &operator++();
+    iterator operator++(int);
+    bool operator!=(const iterator &other) const;
+    bool operator==(const iterator &other) const;
+    _Type &operator*();
+    _Type *operator->();
+  };
+
+  class const_iterator {
+  public:
+    const_iterator() = default;
+    const_iterator(const iterator &) {}
+    const_iterator(decltype(nullptr)) {}
+    const_iterator &operator++();
+    const_iterator operator++(int);
+    bool operator!=(const const_iterator &other) const;
+    bool operator==(const const_iterator &other) const;
+    const _Type &operator*() const;
+    const _Type *operator->() const;
+  };
+
   ~basic_string();
 
   const C *c_str() const;
@@ -75,6 +98,10 @@ struct basic_string {
   _Type& insert(size_type pos, const C* s);
   _Type& insert(size_type pos, const C* s, size_type n);
 
+  basic_string& erase(size_type pos = 0, size_type n = npos);
+  iterator erase(const_iterator position);
+  iterator erase(const_iterator first, const_iterator last);
+
   _Type substr(size_type pos = 0, size_type count = npos) const;
 
   constexpr bool starts_with(std::basic_string_view<C, T> sv) const noexcept;
@@ -94,6 +121,10 @@ struct basic_string {
   _Type& operator=(const _Type& str);
   _Type& operator=(const C* s);
   _Type& operator=(C ch);
+    iterator       begin() noexcept;                                           
                 // constexpr since C++20
+    const_iterator begin() const noexcept;                                     
                 // constexpr since C++20
+    iterator       end() noexcept;                                             
                 // constexpr since C++20
+    const_iterator end() const noexcept;                                       
                 // constexpr since C++20
 
   static constexpr size_t npos = -1;
 };

>From fb1ab37ab876338a7c6ea1140128b998a50bdd3f Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Tue, 12 May 2026 22:36:31 +0200
Subject: [PATCH 07/11] fix clang-tidy issue

---
 .../docs/clang-tidy/checks/modernize/use-std-erase.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
index b0a1f26bdb45b..29eba4932053d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
@@ -8,9 +8,9 @@ for improved readability.
 
 Covered scenarios:
 
-================================================================ 
============================
+=========================================================== ===================
 Expression                                                       Replacement
----------------------------------------------------------------- 
----------------------------
-``v.erase(std::remove(v.begin(), v.end(), 5), v.end())``         
``std::erase(v, 5)``
-``l.erase(std::remove_if(l.begin(), l.end(), isEven), l.end())`` 
``std::erase_if(l, isEven)``
-================================================================ 
============================
+----------------------------------------------------------- -------------------
+``v.erase(remove(v.begin(), v.end(), 5), v.end())``         ``erase(v, 5)``
+``l.erase(remove_if(l.begin(), l.end(), func), l.end())`` ``erase_if(l, func)``
+==========================================================  ===================

>From 196d380227fbb44a5031344402469710f7cf823d Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Wed, 13 May 2026 06:54:16 +0200
Subject: [PATCH 08/11] fix clang-tidy issue

---
 .../clang-tidy/modernize/UseStdEraseCheck.cpp          |  1 -
 .../docs/clang-tidy/checks/modernize/use-std-erase.rst | 10 +++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index dec4885a86231..bf467251658aa 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -14,7 +14,6 @@
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/Lexer.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include <cassert>
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
index 29eba4932053d..3e6009d3a1ffe 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-erase.rst
@@ -8,9 +8,9 @@ for improved readability.
 
 Covered scenarios:
 
-=========================================================== ===================
-Expression                                                       Replacement
------------------------------------------------------------ -------------------
-``v.erase(remove(v.begin(), v.end(), 5), v.end())``         ``erase(v, 5)``
+========================================================= =====================
+Expression                                                Replacement
+--------------------------------------------------------- ---------------------
+``v.erase(remove(v.begin(), v.end(), 5), v.end())``       ``erase(v, 5)``
 ``l.erase(remove_if(l.begin(), l.end(), func), l.end())`` ``erase_if(l, func)``
-==========================================================  ===================
+========================================================= =====================

>From 24c3c470872d914b9787aba4e22275586e91487d Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Wed, 13 May 2026 06:57:01 +0200
Subject: [PATCH 09/11] address comment

---
 .../clang-tidy/modernize/UseStdEraseCheck.cpp         | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index bf467251658aa..478b0c8a16afe 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -8,16 +8,7 @@
 
 #include "UseStdEraseCheck.h"
 #include "../utils/Matchers.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/ASTMatchers/ASTMatchersInternal.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include <cassert>
-#include <initializer_list>
+#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 

>From bc132fe97dc64abde5772224f9e0e4aba80a8078 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Thu, 14 May 2026 19:49:35 +0200
Subject: [PATCH 10/11] address comments

---
 .../clang-tidy/modernize/UseStdEraseCheck.cpp          | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index 478b0c8a16afe..48df3fc47892f 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -37,7 +37,7 @@ makeExprMatcher(const ast_matchers::internal::Matcher<Expr> 
&ArgumentMatcher,
 }
 
 static ast_matchers::internal::Matcher<Expr> makeMatcherPair() {
-  ast_matchers::internal::Matcher<CallExpr> ArgumentMatcher = allOf(
+  const ast_matchers::internal::Matcher<CallExpr> ArgumentMatcher = allOf(
       hasArgument(
           0, makeExprMatcher(expr(unless(hasSideEffects())).bind(EraseThis),
                              {"begin"}, {"::std::begin"})),
@@ -80,18 +80,14 @@ void UseStdEraseCheck::check(const MatchFinder::MatchResult 
&Result) {
   const auto *ContainerThis = Result.Nodes.getNodeAs<Expr>(EraseThis);
   const auto *ValueOrCond = Result.Nodes.getNodeAs<Expr>("valueOrCond");
 
-  if (!EraseCall || !RemoveCall || !ContainerThis || !ValueOrCond)
-    return;
-
-  const CXXMethodDecl *EraseMethod = EraseCall->getMethodDecl();
-  assert(EraseMethod);
+  assert(EraseCall && RemoveCall && ContainerThis && ValueOrCond);
 
   const StringRef RemoveFuncName = RemoveCall->getDirectCallee()->getName();
 
   const StringRef ReplacementFreeFunc =
       RemoveFuncName == "remove" ? "std::erase" : "std::erase_if";
 
-  std::string Replacement =
+  const std::string Replacement =
       (ReplacementFreeFunc + llvm::Twine{"("} +
        Lexer::getSourceText(
            CharSourceRange::getTokenRange(ContainerThis->getSourceRange()),

>From 22bf66748f886454125a27aa2d79a06626ce26e8 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <[email protected]>
Date: Thu, 14 May 2026 19:59:40 +0200
Subject: [PATCH 11/11] fix clang-tidy issue

---
 clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
index 48df3fc47892f..2f6e17fa1abe9 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdEraseCheck.cpp
@@ -99,7 +99,7 @@ void UseStdEraseCheck::check(const MatchFinder::MatchResult 
&Result) {
        llvm::Twine{")"})
           .str();
 
-  DiagnosticBuilder Diag =
+  const DiagnosticBuilder Diag =
       diag(EraseCall->getExprLoc(), "prefer %0 over the erase-%1 idiom")
       << ReplacementFreeFunc << RemoveFuncName;
 

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

Reply via email to