https://github.com/serge-sans-paille updated 
https://github.com/llvm/llvm-project/pull/204789

>From fa0465b09df494651c5efc88cd46d82e7f3e03cc Mon Sep 17 00:00:00 2001
From: serge-sans-paille <[email protected]>
Date: Fri, 19 Jun 2026 11:29:35 +0200
Subject: [PATCH 1/2] [clang-tidy] Extend `modernize-type-traits` to fold
 remove_cv_t<remove_reference_t<...>> into remove_cv_ref_t

---
 .../clang-tidy/modernize/TypeTraitsCheck.cpp  | 29 +++++++++++++++++++
 clang-tools-extra/docs/ReleaseNotes.rst       |  4 +++
 .../checks/modernize/type-traits.rst          |  3 ++
 .../modernize/type-traits-remove-cvref.cpp    | 27 +++++++++++++++++
 4 files changed, 63 insertions(+)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-remove-cvref.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
index 0d03006750d07..7c43219375cdb 100644
--- a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
@@ -196,6 +196,20 @@ void TypeTraitsCheck::registerMatchers(MatchFinder 
*Finder) {
                        this);
   }
   Finder->addMatcher(typeLoc(isType()).bind(Bind), this);
+
+  // Only register matchers for std::remove_cvref_t simplification in c++20
+  // mode.
+  if (getLangOpts().CPlusPlus20) {
+    Finder->addMatcher(templateSpecializationTypeLoc(
+                           loc(qualType(hasDeclaration(
+                               namedDecl(hasName("::std::remove_cv_t"))))),
+                           hasTemplateArgumentLoc(
+                               0, hasTypeLoc(templateSpecializationTypeLoc(loc(
+                                      
qualType(hasDeclaration(namedDecl(hasName(
+                                          "::std::remove_reference_t")))))))))
+                           .bind("remove_cvref"),
+                       this);
+  }
 }
 
 static bool isNamedDeclInStdTraitsSet(const NamedDecl *ND,
@@ -308,6 +322,21 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult 
&Result) {
                       DNTL->getElaboratedKeywordLoc());
     return;
   }
+
+  if (const auto *TSTL = Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
+          "remove_cvref")) {
+    auto Diag = diag(TSTL->getBeginLoc(), "use c++20 type alias");
+    TemplateSpecializationTypeLoc OuterTL =
+        TSTL->getArgLoc(0)
+            .getTypeSourceInfo()
+            ->getTypeLoc()
+            .castAs<TemplateSpecializationTypeLoc>();
+    Diag << FixItHint::CreateReplacement(
+                SourceRange(TSTL->getBeginLoc(), OuterTL.getLAngleLoc()),
+                "std::remove_cvref_t<")
+         << FixItHint::CreateRemoval(OuterTL.getRAngleLoc());
+    return;
+  }
 }
 
 void TypeTraitsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 64dad5fc29905..92443f2b6e6b7 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -616,6 +616,10 @@ Changes in existing checks
   <clang-tidy/checks/modernize/return-braced-init-list>` check to apply fix-it
   when type qualifiers and/or reference modifiers are used with parameters.
 
+- Improved :doc:`modernize-type-traits
+  <clang-tidy/checks/modernize/type-traits>` check to suggest usage of
+  ``std::remove_cvref_t`` when applicable.
+
 - Improved :doc:`modernize-use-default-member-init
   <clang-tidy/checks/modernize/use-default-member-init>` check by fixing a
   false positive when a constructor initializer refers to a declaration that
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/type-traits.rst 
b/clang-tools-extra/docs/clang-tidy/checks/modernize/type-traits.rst
index fbe2b856c6b85..f5ff8bdf5524e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/type-traits.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/type-traits.rst
@@ -25,6 +25,9 @@ Would be converted into:
   std::add_const_t<T>
   std::make_signed_t<unsigned>
 
+Also suggests converting ``std::remove_cv_t<std::remove_reference_t<...>`` into
+``std::remove_cvref_t<...>`` when targeting C++20 or above.
+
 Options
 -------
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-remove-cvref.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-remove-cvref.cpp
new file mode 100644
index 0000000000000..38d3d235d5d4b
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-remove-cvref.cpp
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-type-traits %t
+
+namespace std {
+template <class> struct remove_cv {
+  using type = int;
+};
+template <class T>
+using remove_cv_t = typename remove_cv<T>::type; // NOLINT
+
+template <class> struct remove_reference {
+  using type = int;
+};
+template <class T>
+using remove_reference_t = typename remove_reference<T>::type; // NOLINT
+}
+
+using foo = std::remove_cv_t<std::remove_reference_t<int>>;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use c++20 type alias
+// CHECK-FIXES: using foo = std::remove_cvref_t<int>;
+
+std::remove_cv_t<std::remove_reference_t<int>> var;
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use c++20 type alias
+// CHECK-FIXES: std::remove_cvref_t<int> var;
+
+template<class=std::remove_cv_t<std::remove_reference_t<int>>> struct Foo {};
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use c++20 type alias
+// CHECK-FIXES: template<class=std::remove_cvref_t<int>> struct Foo {};

>From 4a90a8c4183bacb5c11ac8d2b4d9f31f7bf8d766 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <[email protected]>
Date: Fri, 19 Jun 2026 11:45:32 +0200
Subject: [PATCH 2/2] fixup! [clang-tidy] Extend `modernize-type-traits` to
 fold remove_cv_t<remove_reference_t<...>> into remove_cv_ref_t

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

diff --git a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
index 7c43219375cdb..6264a49479902 100644
--- a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
@@ -326,7 +326,7 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult 
&Result) {
   if (const auto *TSTL = Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "remove_cvref")) {
     auto Diag = diag(TSTL->getBeginLoc(), "use c++20 type alias");
-    TemplateSpecializationTypeLoc OuterTL =
+    auto OuterTL =
         TSTL->getArgLoc(0)
             .getTypeSourceInfo()
             ->getTypeLoc()

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

Reply via email to