[clang-tools-extra] [clang-tidy] Fix modernize-use-nullptr false positive on ordering comparisons (PR #225585)
Peiqi Li via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 23 04:11:05 PDT 2026
https://github.com/voyager-jhk updated https://github.com/llvm/llvm-project/pull/225585
>From a7704e7c5361f782ea9042bdb2d14f7f3289ae3f Mon Sep 17 00:00:00 2001
From: voyager-jhk <voyager.lpq at gmail.com>
Date: Wed, 23 Sep 2026 12:20:45 +0800
Subject: [PATCH] [clang-tidy] Fix modernize-use-nullptr false positive on
ordering comparisons
libstdc++ 16 renamed __cmp_cat::__unspec to __cmp_cat::__literal_zero.
Add the new name to the default IgnoredTypes.
Fixes #206245
---
.../clang-tidy/modernize/UseNullptrCheck.cpp | 8 +++++--
clang-tools-extra/docs/ReleaseNotes.md | 5 +++++
.../checks/modernize/use-nullptr.rst | 2 +-
.../checkers/modernize/use-nullptr-cxx20.cpp | 21 +++++++++++++++++++
4 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index 01bb98cfbcfd4e..42a16c87398083 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -38,6 +38,10 @@ AST_MATCHER(DecltypeType, decltypeTypeNullptrLiteral) {
static constexpr char CastSequence[] = "sequence";
+static constexpr char DefaultIgnoredTypes[] = "std::_CmpUnspecifiedParam;"
+ "^std::__cmp_cat::__unspec;"
+ "^std::__cmp_cat::__literal_zero";
+
/// Create a matcher that finds implicit casts as well as the head of a
/// sequence of zero or more nested explicit casts that have an implicit cast
/// to null within.
@@ -505,8 +509,8 @@ class CastSequenceVisitor : public RecursiveASTVisitor<CastSequenceVisitor> {
UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
- IgnoredTypes(utils::options::parseStringList(Options.get(
- "IgnoredTypes", "_CmpUnspecifiedParam;^std::__cmp_cat::__unspec"))),
+ IgnoredTypes(utils::options::parseStringList(
+ Options.get("IgnoredTypes", DefaultIgnoredTypes))),
UseNullptrT(Options.get("UseNullptrT", true)),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index d0906f9ee6be81..d72f5cb9a0d185 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -240,6 +240,11 @@ infrastructure are described first, followed by tool-specific sections.
<clang-tidy/checks/modernize/use-nullptr>` to turn `decltype(nullptr)` into
`std::nullptr_t` from `<cstdef>`.
+- Improved {doc}`modernize-use-nullptr
+ <clang-tidy/checks/modernize/use-nullptr>` check to avoid replacing `0`
+ with `nullptr` in comparisons with ordering types such as
+ `std::strong_ordering`.
+
- Improved {doc}`performance-inefficient-algorithm
<clang-tidy/checks/performance/inefficient-algorithm>` check to no longer
produce a fix with the container or the searched-for value missing, such as
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst
index ce43e1e4eb5dc5..ab33ec5f0957cf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst
@@ -53,7 +53,7 @@ Options
Semicolon-separated list of regular expressions to match pointer types for
which implicit casts will be ignored. Default value:
- `std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec`.
+ `std::_CmpUnspecifiedParam::;^std::__cmp_cat::__unspec;^std::__cmp_cat::__literal_zero`.
.. option:: NullMacros
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp
index 2cd2f1e07b0b12..3000ad0160eb65 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-cxx20.cpp
@@ -1,4 +1,5 @@
// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-nullptr %t -- -- -DGCC
+// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-nullptr %t -- -- -DGCC_LITERAL_ZERO
// RUN: %check_clang_tidy -std=c++20-or-later %s modernize-use-nullptr %t -- -- -DCLANG
namespace std {
@@ -24,6 +25,17 @@ namespace __cmp_cat {
#define UNSPECIFIED_TYPE __cmp_cat::__unspec
#endif
+// libstdc++ 16 renamed __cmp_cat::__unspec to __cmp_cat::__literal_zero.
+#ifdef GCC_LITERAL_ZERO
+namespace __cmp_cat {
+ struct __literal_zero {
+ consteval __literal_zero(__literal_zero*) noexcept { }
+ };
+}
+
+#define UNSPECIFIED_TYPE __cmp_cat::__literal_zero
+#endif
+
struct strong_ordering {
signed char value;
@@ -82,6 +94,15 @@ void testValidZero() {
// CHECK-FIXES: if (result < 0) {}
}
+void testOrderingConstantsComparedWithZero() {
+ void(std::strong_ordering::equal == 0);
+ // CHECK-FIXES: void(std::strong_ordering::equal == 0);
+ void(std::strong_ordering::less == 0);
+ // CHECK-FIXES: void(std::strong_ordering::less == 0);
+ void(std::strong_ordering::greater == 0);
+ // CHECK-FIXES: void(std::strong_ordering::greater == 0);
+}
+
template<class T1, class T2>
struct P {
T1 x1;
More information about the cfe-commits
mailing list