https://github.com/hjanuschka updated 
https://github.com/llvm/llvm-project/pull/118074

>From cb748c34d35b8c0c9ca93a67b111dcf5d7665b34 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:17:49 +0100
Subject: [PATCH 01/11] [clang-tidy] Add modernize-use-span-first-last check

Add new check that modernizes std::span::subspan() calls to use the more
expressive first() and last() member functions where applicable.
---
 .../clang-tidy/modernize/CMakeLists.txt       |  1 +
 .../modernize/ModernizeTidyModule.cpp         |  3 +
 .../modernize/UseSpanFirstLastCheck.cpp       | 97 +++++++++++++++++++
 .../modernize/UseSpanFirstLastCheck.h         | 40 ++++++++
 clang-tools-extra/docs/ReleaseNotes.rst       |  4 +
 .../checks/modernize/use-span-first-last.rst  | 19 ++++
 .../modernize-subspan-conversion.cpp          | 50 ++++++++++
 7 files changed, 214 insertions(+)
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
 create mode 100644 
clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index c919d49b42873a..47dd12a2640b6c 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -49,6 +49,7 @@ add_clang_library(clangTidyModernizeModule STATIC
   UseTransparentFunctorsCheck.cpp
   UseUncaughtExceptionsCheck.cpp
   UseUsingCheck.cpp
+  UseSpanFirstLastCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 18607593320635..6fc5de5aad20b7 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,6 +42,7 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseRangesCheck.h"
+#include "UseSpanFirstLastCheck.h"
 #include "UseStartsEndsWithCheck.h"
 #include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
@@ -122,6 +123,8 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<UseUncaughtExceptionsCheck>(
         "modernize-use-uncaught-exceptions");
     CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using");
+    
CheckFactories.registerCheck<UseSpanFirstLastCheck>("modernize-use-span-first-last");
+
   }
 };
 
diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
new file mode 100644
index 00000000000000..f57571f2aa7c86
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
@@ -0,0 +1,97 @@
+//===--- UseSpanFirstLastCheck.cpp - clang-tidy-----------------*- C++ -*-===//
+//
+// 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 "UseSpanFirstLastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+
+void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) {
+  // Match span::subspan calls
+  const auto HasSpanType = hasType(hasUnqualifiedDesugaredType(
+      recordType(hasDeclaration(classTemplateSpecializationDecl(
+          hasName("::std::span"))))));
+
+  Finder->addMatcher(
+      cxxMemberCallExpr(
+          callee(memberExpr(hasDeclaration(
+              cxxMethodDecl(hasName("subspan"))))),
+          on(expr(HasSpanType)))
+          .bind("subspan"),
+      this);
+}
+
+void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("subspan");
+  if (!Call)
+    return;
+
+  handleSubspanCall(Result, Call);
+}
+
+void UseSpanFirstLastCheck::handleSubspanCall(
+    const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) {
+  // Get arguments
+  unsigned NumArgs = Call->getNumArgs();
+  if (NumArgs == 0 || NumArgs > 2)
+    return;
+
+  const Expr *Offset = Call->getArg(0);
+  const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr;
+  auto &Context = *Result.Context;
+  bool IsZeroOffset = false;
+
+  // Check if offset is zero through any implicit casts
+  const Expr* OffsetE = Offset->IgnoreImpCasts();
+  if (const auto *IL = dyn_cast<IntegerLiteral>(OffsetE)) {
+    IsZeroOffset = IL->getValue() == 0;
+  }
+
+  // Build replacement text
+  std::string Replacement;
+  if (IsZeroOffset && Count) {
+    // subspan(0, count) -> first(count)
+    auto CountStr = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(Count->getSourceRange()),
+        Context.getSourceManager(), Context.getLangOpts());
+    const auto *Base = 
cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
+    auto BaseStr = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(Base->getSourceRange()),
+        Context.getSourceManager(), Context.getLangOpts());
+    Replacement = BaseStr.str() + ".first(" + CountStr.str() + ")";
+  } else if (NumArgs == 1) {
+    // subspan(n) -> last(size() - n)
+    auto OffsetStr = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(Offset->getSourceRange()),
+        Context.getSourceManager(), Context.getLangOpts());
+    
+    const auto *Base = 
cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
+    auto BaseStr = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(Base->getSourceRange()),
+        Context.getSourceManager(), Context.getLangOpts());
+    
+    Replacement = BaseStr.str() + ".last(" + BaseStr.str() + ".size() - " + 
OffsetStr.str() + ")";
+  }
+
+  if (!Replacement.empty()) {
+    if (IsZeroOffset && Count) {
+        diag(Call->getBeginLoc(), "prefer span::first() over subspan()")
+            << FixItHint::CreateReplacement(Call->getSourceRange(), 
Replacement);
+    } else {
+        diag(Call->getBeginLoc(), "prefer span::last() over subspan()")
+            << FixItHint::CreateReplacement(Call->getSourceRange(), 
Replacement);
+    }
+  }
+}
+
+} // namespace clang::tidy::modernize
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
new file mode 100644
index 00000000000000..141b848be9abbb
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
@@ -0,0 +1,40 @@
+//===--- UseSpanFirstLastCheck.h - clang-tidy-------------------*- C++ -*-===//
+//
+// 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_USESPANFIRSTLASTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::modernize {
+
+/// Converts std::span::subspan() calls to the more modern first()/last() 
methods
+/// where applicable.
+///
+/// For example:
+/// \code
+///   std::span<int> s = ...;
+///   auto sub = s.subspan(0, n);    // ->  auto sub = s.first(n);
+///   auto sub2 = s.subspan(n);      // ->  auto sub2 = s.last(s.size() - n);
+/// \endcode
+class UseSpanFirstLastCheck : public ClangTidyCheck {
+public:
+  UseSpanFirstLastCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  void handleSubspanCall(const ast_matchers::MatchFinder::MatchResult &Result,
+                        const CXXMemberCallExpr *Call);
+};
+
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H
\ No newline at end of file
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index f050391110385e..04a45d002c0d1d 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,6 +145,10 @@ New checks
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
+- New check `modernize-use-span-first-last` has been added that suggests using
+  ``std::span::first()`` and ``std::span::last()`` member functions instead of
+  equivalent ``subspan()``.
+
 - New alias :doc:`cert-arr39-c <clang-tidy/checks/cert/arr39-c>` to
   :doc:`bugprone-sizeof-expression
   <clang-tidy/checks/bugprone/sizeof-expression>` was added.
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst
new file mode 100644
index 00000000000000..e8aad59bb2264f
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst
@@ -0,0 +1,19 @@
+.. title:: clang-tidy - modernize-use-span-first-last
+
+modernize-use-span-first-last
+============================
+
+Checks for uses of ``std::span::subspan()`` that can be replaced with clearer
+``first()`` or ``last()`` member functions.
+
+Covered scenarios:
+
+==================================== ==================================
+Expression                           Replacement
+------------------------------------ ----------------------------------
+``s.subspan(0, n)``                  ``s.first(n)``
+``s.subspan(n)``                     ``s.last(s.size() - n)``
+==================================== ==================================
+
+Non-zero offset with count (like ``subspan(1, n)``) has no direct equivalent
+using ``first()`` or ``last()``, so these cases are not transformed.
\ No newline at end of file
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
new file mode 100644
index 00000000000000..cb78bc02f22d4f
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy %s modernize-use-span-first-last %t
+
+namespace std {
+template <typename T>
+class span {
+  T* ptr;
+  __SIZE_TYPE__ len;
+
+public:
+  span(T* p, __SIZE_TYPE__ l) : ptr(p), len(l) {}
+  
+  span<T> subspan(__SIZE_TYPE__ offset) const {
+    return span(ptr + offset, len - offset);
+  }
+  
+  span<T> subspan(__SIZE_TYPE__ offset, __SIZE_TYPE__ count) const {
+    return span(ptr + offset, count);
+  }
+
+  span<T> first(__SIZE_TYPE__ count) const {
+    return span(ptr, count);
+  }
+
+  span<T> last(__SIZE_TYPE__ count) const {
+    return span(ptr + (len - count), count);
+  }
+
+  __SIZE_TYPE__ size() const { return len; }
+};
+} // namespace std
+
+void test() {
+  int arr[] = {1, 2, 3, 4, 5};
+  std::span<int> s(arr, 5);
+
+  auto sub1 = s.subspan(0, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer span::first() over 
subspan()
+  // CHECK-FIXES: auto sub1 = s.first(3);
+
+  auto sub2 = s.subspan(2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer span::last() over 
subspan()
+  // CHECK-FIXES: auto sub2 = s.last(s.size() - 2);
+
+  __SIZE_TYPE__ n = 2;
+  auto sub3 = s.subspan(0, n);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer span::first() over 
subspan()
+  // CHECK-FIXES: auto sub3 = s.first(n);
+
+  auto sub4 = s.subspan(1, 2);  // No warning
+}
\ No newline at end of file

>From ec5a6b0ceb0fbbf03ea36a38fb627b25ab4e62de Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:19:21 +0100
Subject: [PATCH 02/11] format

---
 .../modernize/UseSpanFirstLastCheck.cpp       | 41 ++++++++++---------
 .../modernize/UseSpanFirstLastCheck.h         |  6 +--
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
index f57571f2aa7c86..6cf01386b0c3fb 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
@@ -18,17 +18,15 @@ namespace clang::tidy::modernize {
 
 void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) {
   // Match span::subspan calls
-  const auto HasSpanType = hasType(hasUnqualifiedDesugaredType(
-      recordType(hasDeclaration(classTemplateSpecializationDecl(
-          hasName("::std::span"))))));
+  const auto HasSpanType =
+      hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+          classTemplateSpecializationDecl(hasName("::std::span"))))));
 
-  Finder->addMatcher(
-      cxxMemberCallExpr(
-          callee(memberExpr(hasDeclaration(
-              cxxMethodDecl(hasName("subspan"))))),
-          on(expr(HasSpanType)))
-          .bind("subspan"),
-      this);
+  Finder->addMatcher(cxxMemberCallExpr(callee(memberExpr(hasDeclaration(
+                                           
cxxMethodDecl(hasName("subspan"))))),
+                                       on(expr(HasSpanType)))
+                         .bind("subspan"),
+                     this);
 }
 
 void UseSpanFirstLastCheck::check(const MatchFinder::MatchResult &Result) {
@@ -52,7 +50,7 @@ void UseSpanFirstLastCheck::handleSubspanCall(
   bool IsZeroOffset = false;
 
   // Check if offset is zero through any implicit casts
-  const Expr* OffsetE = Offset->IgnoreImpCasts();
+  const Expr *OffsetE = Offset->IgnoreImpCasts();
   if (const auto *IL = dyn_cast<IntegerLiteral>(OffsetE)) {
     IsZeroOffset = IL->getValue() == 0;
   }
@@ -64,7 +62,8 @@ void UseSpanFirstLastCheck::handleSubspanCall(
     auto CountStr = Lexer::getSourceText(
         CharSourceRange::getTokenRange(Count->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
-    const auto *Base = 
cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
+    const auto *Base =
+        cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
     auto BaseStr = Lexer::getSourceText(
         CharSourceRange::getTokenRange(Base->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
@@ -74,22 +73,24 @@ void UseSpanFirstLastCheck::handleSubspanCall(
     auto OffsetStr = Lexer::getSourceText(
         CharSourceRange::getTokenRange(Offset->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
-    
-    const auto *Base = 
cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
+
+    const auto *Base =
+        cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
     auto BaseStr = Lexer::getSourceText(
         CharSourceRange::getTokenRange(Base->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
-    
-    Replacement = BaseStr.str() + ".last(" + BaseStr.str() + ".size() - " + 
OffsetStr.str() + ")";
+
+    Replacement = BaseStr.str() + ".last(" + BaseStr.str() + ".size() - " +
+                  OffsetStr.str() + ")";
   }
 
   if (!Replacement.empty()) {
     if (IsZeroOffset && Count) {
-        diag(Call->getBeginLoc(), "prefer span::first() over subspan()")
-            << FixItHint::CreateReplacement(Call->getSourceRange(), 
Replacement);
+      diag(Call->getBeginLoc(), "prefer span::first() over subspan()")
+          << FixItHint::CreateReplacement(Call->getSourceRange(), Replacement);
     } else {
-        diag(Call->getBeginLoc(), "prefer span::last() over subspan()")
-            << FixItHint::CreateReplacement(Call->getSourceRange(), 
Replacement);
+      diag(Call->getBeginLoc(), "prefer span::last() over subspan()")
+          << FixItHint::CreateReplacement(Call->getSourceRange(), Replacement);
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h 
b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
index 141b848be9abbb..8d4c6035f7ec76 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
@@ -13,8 +13,8 @@
 
 namespace clang::tidy::modernize {
 
-/// Converts std::span::subspan() calls to the more modern first()/last() 
methods
-/// where applicable.
+/// Converts std::span::subspan() calls to the more modern first()/last()
+/// methods where applicable.
 ///
 /// For example:
 /// \code
@@ -32,7 +32,7 @@ class UseSpanFirstLastCheck : public ClangTidyCheck {
 
 private:
   void handleSubspanCall(const ast_matchers::MatchFinder::MatchResult &Result,
-                        const CXXMemberCallExpr *Call);
+                         const CXXMemberCallExpr *Call);
 };
 
 } // namespace clang::tidy::modernize

>From 5cf1b7ce1fcaf87a26f1ad1ff0d265a47613c144 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:28:42 +0100
Subject: [PATCH 03/11] format

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

diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 6fc5de5aad20b7..c473c80e3cd0eb 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -123,7 +123,8 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<UseUncaughtExceptionsCheck>(
         "modernize-use-uncaught-exceptions");
     CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using");
-    
CheckFactories.registerCheck<UseSpanFirstLastCheck>("modernize-use-span-first-last");
+    CheckFactories.registerCheck<UseSpanFirstLastCheck>(
+        "modernize-use-span-first-last");
 
   }
 };

>From b357f8c8fe607924ba6c5537f42ebfffaa09c011 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:36:31 +0100
Subject: [PATCH 04/11] format

---
 clang-tools-extra/clang-tidy/modernize/CMakeLists.txt  |  1 -
 .../clang-tidy/modernize/ModernizeTidyModule.cpp       |  3 ---
 .../clang-tidy/readability/CMakeLists.txt              |  1 +
 .../clang-tidy/readability/ReadabilityTidyModule.cpp   |  3 +++
 .../UseSpanFirstLastCheck.cpp                          |  4 ++--
 .../{modernize => readability}/UseSpanFirstLastCheck.h | 10 +++++-----
 clang-tools-extra/docs/ReleaseNotes.rst                |  2 +-
 .../use-starts-ends-with.rst                           |  4 ++--
 .../use-span-first-last.cpp}                           |  2 +-
 9 files changed, 15 insertions(+), 15 deletions(-)
 rename clang-tools-extra/clang-tidy/{modernize => 
readability}/UseSpanFirstLastCheck.cpp (97%)
 rename clang-tools-extra/clang-tidy/{modernize => 
readability}/UseSpanFirstLastCheck.h (79%)
 rename clang-tools-extra/docs/clang-tidy/checks/{modernize => 
readability}/use-starts-ends-with.rst (92%)
 rename 
clang-tools-extra/test/clang-tidy/checkers/{modernize/modernize-subspan-conversion.cpp
 => readability/use-span-first-last.cpp} (95%)

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 47dd12a2640b6c..c919d49b42873a 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -49,7 +49,6 @@ add_clang_library(clangTidyModernizeModule STATIC
   UseTransparentFunctorsCheck.cpp
   UseUncaughtExceptionsCheck.cpp
   UseUsingCheck.cpp
-  UseSpanFirstLastCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index c473c80e3cd0eb..b2a8f9dd20adba 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -42,7 +42,6 @@
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
 #include "UseRangesCheck.h"
-#include "UseSpanFirstLastCheck.h"
 #include "UseStartsEndsWithCheck.h"
 #include "UseStdFormatCheck.h"
 #include "UseStdNumbersCheck.h"
@@ -123,8 +122,6 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<UseUncaughtExceptionsCheck>(
         "modernize-use-uncaught-exceptions");
     CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using");
-    CheckFactories.registerCheck<UseSpanFirstLastCheck>(
-        "modernize-use-span-first-last");
 
   }
 };
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8f303c51e1b0da..f9f9e8e7f19685 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -58,6 +58,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
   UppercaseLiteralSuffixCheck.cpp
   UseAnyOfAllOfCheck.cpp
   UseStdMinMaxCheck.cpp
+  UseSpanFirstLastCheck.cpp
 
   LINK_LIBS
   clangTidy
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d61c0ba39658e5..9729d080f63a84 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -60,6 +60,7 @@
 #include "UniqueptrDeleteReleaseCheck.h"
 #include "UppercaseLiteralSuffixCheck.h"
 #include "UseAnyOfAllOfCheck.h"
+#include "UseSpanFirstLastCheck.h"
 #include "UseStdMinMaxCheck.h"
 
 namespace clang::tidy {
@@ -172,6 +173,8 @@ class ReadabilityModule : public ClangTidyModule {
         "readability-use-anyofallof");
     CheckFactories.registerCheck<UseStdMinMaxCheck>(
         "readability-use-std-min-max");
+    CheckFactories.registerCheck<UseSpanFirstLastCheck>(
+        "readability-use-span-first-last");
   }
 };
 
diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
similarity index 97%
rename from clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
rename to clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
index 6cf01386b0c3fb..da7d147565fbdf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
@@ -14,7 +14,7 @@
 
 using namespace clang::ast_matchers;
 
-namespace clang::tidy::modernize {
+namespace clang::tidy::readability {
 
 void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) {
   // Match span::subspan calls
@@ -95,4 +95,4 @@ void UseSpanFirstLastCheck::handleSubspanCall(
   }
 }
 
-} // namespace clang::tidy::modernize
\ No newline at end of file
+} // namespace clang::tidy::readability
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
similarity index 79%
rename from clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
rename to clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
index 8d4c6035f7ec76..271730ed4985a3 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseSpanFirstLastCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
@@ -6,12 +6,12 @@
 //
 
//===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESPANFIRSTLASTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESPANFIRSTLASTCHECK_H
 
 #include "../ClangTidyCheck.h"
 
-namespace clang::tidy::modernize {
+namespace clang::tidy::readability {
 
 /// Converts std::span::subspan() calls to the more modern first()/last()
 /// methods where applicable.
@@ -35,6 +35,6 @@ class UseSpanFirstLastCheck : public ClangTidyCheck {
                          const CXXMemberCallExpr *Call);
 };
 
-} // namespace clang::tidy::modernize
+} // namespace clang::tidy::readability
 
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESPANFIRSTLASTCHECK_H
\ No newline at end of file
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESPANFIRSTLASTCHECK_H
\ No newline at end of file
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 04a45d002c0d1d..a52b778a27b5f4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,7 +145,7 @@ New checks
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
-- New check `modernize-use-span-first-last` has been added that suggests using
+- New check `readability-use-span-first-last` has been added that suggests 
using
   ``std::span::first()`` and ``std::span::last()`` member functions instead of
   equivalent ``subspan()``.
 
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst 
b/clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst
similarity index 92%
rename from 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
rename to 
clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst
index 78cd900885ac3f..ff5c0d53feeb15 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst
@@ -1,6 +1,6 @@
-.. title:: clang-tidy - modernize-use-starts-ends-with
+.. title:: clang-tidy - readability-use-starts-ends-with
 
-modernize-use-starts-ends-with
+readability-use-starts-ends-with
 ==============================
 
 Checks for common roundabout ways to express ``starts_with`` and ``ends_with``
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
similarity index 95%
rename from 
clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
rename to 
clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
index cb78bc02f22d4f..93ae95bdd8b6b4 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/modernize-subspan-conversion.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s modernize-use-span-first-last %t
+// RUN: %check_clang_tidy %s readability-use-span-first-last %t
 
 namespace std {
 template <typename T>

>From 42d1df2f5f6b0527d5066a9fbd8ff2f445d2d79a Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:37:32 +0100
Subject: [PATCH 05/11] format

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

diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp 
b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index b2a8f9dd20adba..18607593320635 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -122,7 +122,6 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<UseUncaughtExceptionsCheck>(
         "modernize-use-uncaught-exceptions");
     CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using");
-
   }
 };
 

>From 04f3edc9edb5148652bea8a8b5066f32d321ed2b Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:37:47 +0100
Subject: [PATCH 06/11] format

---
 .../checks/modernize/use-span-first-last.rst  | 19 -------------------
 1 file changed, 19 deletions(-)
 delete mode 100644 
clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst

diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst
deleted file mode 100644
index e8aad59bb2264f..00000000000000
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-span-first-last.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-.. title:: clang-tidy - modernize-use-span-first-last
-
-modernize-use-span-first-last
-============================
-
-Checks for uses of ``std::span::subspan()`` that can be replaced with clearer
-``first()`` or ``last()`` member functions.
-
-Covered scenarios:
-
-==================================== ==================================
-Expression                           Replacement
------------------------------------- ----------------------------------
-``s.subspan(0, n)``                  ``s.first(n)``
-``s.subspan(n)``                     ``s.last(s.size() - n)``
-==================================== ==================================
-
-Non-zero offset with count (like ``subspan(1, n)``) has no direct equivalent
-using ``first()`` or ``last()``, so these cases are not transformed.
\ No newline at end of file

>From 2f9cc3e878a3c053240a7e6f06b304f89c0d6085 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:43:56 +0100
Subject: [PATCH 07/11] format

---
 .../clang-tidy/readability/UseSpanFirstLastCheck.cpp          | 2 ++
 .../clang-tidy/checkers/readability/use-span-first-last.cpp   | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
index da7d147565fbdf..345a197551d618 100644
--- a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
@@ -17,6 +17,8 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::readability {
 
 void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus20)
+    return;
   // Match span::subspan calls
   const auto HasSpanType =
       hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
index 93ae95bdd8b6b4..d99a535e012fa3 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
@@ -1,4 +1,6 @@
-// RUN: %check_clang_tidy %s readability-use-span-first-last %t
+// RUN: %check_clang_tidy -std=c++20 %s readability-use-span-first-last %t
+
+
 
 namespace std {
 template <typename T>

>From 24690e3a1155b222436b082c4236c933766a8707 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:53:12 +0100
Subject: [PATCH 08/11] up

---
 .../readability/UseSpanFirstLastCheck.cpp     | 34 ++++++++++++-------
 .../readability/use-span-first-last.cpp       |  7 ++--
 2 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
index 345a197551d618..5cd0cd0756e3ba 100644
--- a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.cpp
@@ -19,6 +19,7 @@ namespace clang::tidy::readability {
 void UseSpanFirstLastCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus20)
     return;
+
   // Match span::subspan calls
   const auto HasSpanType =
       hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
@@ -41,7 +42,6 @@ void UseSpanFirstLastCheck::check(const 
MatchFinder::MatchResult &Result) {
 
 void UseSpanFirstLastCheck::handleSubspanCall(
     const MatchFinder::MatchResult &Result, const CXXMemberCallExpr *Call) {
-  // Get arguments
   unsigned NumArgs = Call->getNumArgs();
   if (NumArgs == 0 || NumArgs > 2)
     return;
@@ -49,14 +49,28 @@ void UseSpanFirstLastCheck::handleSubspanCall(
   const Expr *Offset = Call->getArg(0);
   const Expr *Count = NumArgs > 1 ? Call->getArg(1) : nullptr;
   auto &Context = *Result.Context;
-  bool IsZeroOffset = false;
 
-  // Check if offset is zero through any implicit casts
+  // Check if this is subspan(0, n) -> first(n)
+  bool IsZeroOffset = false;
   const Expr *OffsetE = Offset->IgnoreImpCasts();
   if (const auto *IL = dyn_cast<IntegerLiteral>(OffsetE)) {
     IsZeroOffset = IL->getValue() == 0;
   }
 
+  // Check if this is subspan(size() - n) -> last(n)
+  bool IsSizeMinusN = false;
+  const Expr *SizeMinusArg = nullptr;
+  if (const auto *BO = dyn_cast<BinaryOperator>(OffsetE)) {
+    if (BO->getOpcode() == BO_Sub) {
+      if (const auto *SizeCall = dyn_cast<CXXMemberCallExpr>(BO->getLHS())) {
+        if (SizeCall->getMethodDecl()->getName() == "size") {
+          IsSizeMinusN = true;
+          SizeMinusArg = BO->getRHS();
+        }
+      }
+    }
+  }
+
   // Build replacement text
   std::string Replacement;
   if (IsZeroOffset && Count) {
@@ -70,20 +84,17 @@ void UseSpanFirstLastCheck::handleSubspanCall(
         CharSourceRange::getTokenRange(Base->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
     Replacement = BaseStr.str() + ".first(" + CountStr.str() + ")";
-  } else if (NumArgs == 1) {
-    // subspan(n) -> last(size() - n)
-    auto OffsetStr = Lexer::getSourceText(
-        CharSourceRange::getTokenRange(Offset->getSourceRange()),
+  } else if (IsSizeMinusN && SizeMinusArg) {
+    // subspan(size() - n) -> last(n)
+    auto ArgStr = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(SizeMinusArg->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
-
     const auto *Base =
         cast<CXXMemberCallExpr>(Call)->getImplicitObjectArgument();
     auto BaseStr = Lexer::getSourceText(
         CharSourceRange::getTokenRange(Base->getSourceRange()),
         Context.getSourceManager(), Context.getLangOpts());
-
-    Replacement = BaseStr.str() + ".last(" + BaseStr.str() + ".size() - " +
-                  OffsetStr.str() + ")";
+    Replacement = BaseStr.str() + ".last(" + ArgStr.str() + ")";
   }
 
   if (!Replacement.empty()) {
@@ -96,5 +107,4 @@ void UseSpanFirstLastCheck::handleSubspanCall(
     }
   }
 }
-
 } // namespace clang::tidy::readability
\ No newline at end of file
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
index d99a535e012fa3..e775de8b806ad8 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/use-span-first-last.cpp
@@ -1,7 +1,5 @@
 // RUN: %check_clang_tidy -std=c++20 %s readability-use-span-first-last %t
 
-
-
 namespace std {
 template <typename T>
 class span {
@@ -39,9 +37,9 @@ void test() {
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer span::first() over 
subspan()
   // CHECK-FIXES: auto sub1 = s.first(3);
 
-  auto sub2 = s.subspan(2);
+  auto sub2 = s.subspan(s.size() - 2);
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer span::last() over 
subspan()
-  // CHECK-FIXES: auto sub2 = s.last(s.size() - 2);
+  // CHECK-FIXES: auto sub2 = s.last(2);
 
   __SIZE_TYPE__ n = 2;
   auto sub3 = s.subspan(0, n);
@@ -49,4 +47,5 @@ void test() {
   // CHECK-FIXES: auto sub3 = s.first(n);
 
   auto sub4 = s.subspan(1, 2);  // No warning
+  auto sub5 = s.subspan(2);     // No warning
 }
\ No newline at end of file

>From 39833d470eea5a0f446b01dba8bbc8271ec69366 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:56:54 +0100
Subject: [PATCH 09/11] up

---
 .../readability/use-span-first-last.rst       | 23 +++++++++++++++++++
 .../readability/use-starts-ends-with.rst      | 22 ------------------
 2 files changed, 23 insertions(+), 22 deletions(-)
 create mode 100644 
clang-tools-extra/docs/clang-tidy/checks/readability/use-span-first-last.rst
 delete mode 100644 
clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst

diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/readability/use-span-first-last.rst 
b/clang-tools-extra/docs/clang-tidy/checks/readability/use-span-first-last.rst
new file mode 100644
index 00000000000000..1872ed56583acb
--- /dev/null
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/readability/use-span-first-last.rst
@@ -0,0 +1,23 @@
+.. title:: clang-tidy - readability-use-span-first-last
+
+readability-use-span-first-last
+=============================
+
+Checks for uses of ``std::span::subspan()`` that can be replaced with clearer
+``first()`` or ``last()`` member functions. These dedicated methods were added 
+to C++20 to provide more expressive alternatives to common subspan operations.
+
+Covered scenarios:
+
+==================================== ==================================
+Expression                           Replacement
+------------------------------------ ----------------------------------
+``s.subspan(0, n)``                  ``s.first(n)``
+``s.subspan(s.size() - n)``          ``s.last(n)``
+==================================== ==================================
+
+Non-zero offset with count (like ``subspan(1, n)``) or offset-only calls 
+(like ``subspan(n)``) have no clearer equivalent using ``first()`` or 
+``last()``, so these cases are not transformed.
+
+This check is only active when C++20 or later is used.
\ No newline at end of file
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst 
b/clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst
deleted file mode 100644
index ff5c0d53feeb15..00000000000000
--- 
a/clang-tools-extra/docs/clang-tidy/checks/readability/use-starts-ends-with.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-.. title:: clang-tidy - readability-use-starts-ends-with
-
-readability-use-starts-ends-with
-==============================
-
-Checks for common roundabout ways to express ``starts_with`` and ``ends_with``
-and suggests replacing with the simpler method when it is available. Notably, 
-this will work with ``std::string`` and ``std::string_view``.
-
-Covered scenarios:
-
-==================================================== =====================
-Expression                                           Replacement
----------------------------------------------------- ---------------------
-``u.find(v) == 0``                                   ``u.starts_with(v)``
-``u.rfind(v, 0) != 0``                               ``!u.starts_with(v)``
-``u.compare(0, v.size(), v) == 0``                   ``u.starts_with(v)``
-``u.substr(0, v.size()) == v``                       ``u.starts_with(v)``
-``v != u.substr(0, v.size())``                       ``!u.starts_with(v)``
-``u.compare(u.size() - v.size(), v.size(), v) == 0`` ``u.ends_with(v)``
-``u.rfind(v) == u.size() - v.size()``                ``u.ends_with(v)``
-==================================================== =====================

>From 964fadc022c33e0e09217b3f8d9eea25b1e7a215 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 10:59:15 +0100
Subject: [PATCH 10/11] format

---
 .../clang-tidy/readability/UseSpanFirstLastCheck.h   | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
index 271730ed4985a3..354ff6edb83dec 100644
--- a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
@@ -13,15 +13,19 @@
 
 namespace clang::tidy::readability {
 
-/// Converts std::span::subspan() calls to the more modern first()/last()
-/// methods where applicable.
+/// Suggests using clearer std::span member functions first()/last() instead 
of 
+/// equivalent subspan() calls where applicable.
 ///
 /// For example:
 /// \code
 ///   std::span<int> s = ...;
-///   auto sub = s.subspan(0, n);    // ->  auto sub = s.first(n);
-///   auto sub2 = s.subspan(n);      // ->  auto sub2 = s.last(s.size() - n);
+///   auto sub1 = s.subspan(0, n);           // ->  auto sub1 = s.first(n);
+///   auto sub2 = s.subspan(s.size() - n);   // ->  auto sub2 = s.last(n);
+///   auto sub3 = s.subspan(1, n);           // not changed
+///   auto sub4 = s.subspan(n);              // not changed
 /// \endcode
+///
+/// The check is only active in C++20 mode.
 class UseSpanFirstLastCheck : public ClangTidyCheck {
 public:
   UseSpanFirstLastCheck(StringRef Name, ClangTidyContext *Context)

>From 79afa9e924afa4cb827085301e44a66db15ba755 Mon Sep 17 00:00:00 2001
From: Helmut Januschka <hel...@januschka.com>
Date: Fri, 29 Nov 2024 11:21:06 +0100
Subject: [PATCH 11/11] format

---
 .../clang-tidy/readability/UseSpanFirstLastCheck.h              | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h 
b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
index 354ff6edb83dec..84a2d5996a996d 100644
--- a/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseSpanFirstLastCheck.h
@@ -13,7 +13,7 @@
 
 namespace clang::tidy::readability {
 
-/// Suggests using clearer std::span member functions first()/last() instead 
of 
+/// Suggests using clearer std::span member functions first()/last() instead of
 /// equivalent subspan() calls where applicable.
 ///
 /// For example:

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to