[clang-tools-extra] [clang-tidy] Add new check `readability-use-numeric-limits` (PR #127430)
Katherine Whitlock via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 28 08:35:00 PST 2025
https://github.com/stellar-aria updated https://github.com/llvm/llvm-project/pull/127430
>From ba0eef9808b42b01e356cd5c87745f7477e07c68 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Sun, 16 Feb 2025 22:45:06 -0500
Subject: [PATCH 01/10] [clang-tidy] Add new check
`readability-use-numeric-limits`
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../readability/UseNumericLimitsCheck.cpp | 135 ++++++++++++++++++
.../readability/UseNumericLimitsCheck.h | 41 ++++++
clang-tools-extra/docs/ReleaseNotes.rst | 5 +
.../docs/clang-tidy/checks/list.rst | 1 +
.../checks/readability/use-numeric-limits.rst | 22 +++
.../readability/use-numeric-limits.cpp | 85 +++++++++++
8 files changed, 293 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8f303c51e1b0d..e06f68bdda73f 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -57,6 +57,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
UniqueptrDeleteReleaseCheck.cpp
UppercaseLiteralSuffixCheck.cpp
UseAnyOfAllOfCheck.cpp
+ UseNumericLimitsCheck.cpp
UseStdMinMaxCheck.cpp
LINK_LIBS
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d61c0ba39658e..054083d25952a 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 "UseNumericLimitsCheck.h"
#include "UseStdMinMaxCheck.h"
namespace clang::tidy {
@@ -170,6 +171,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-uppercase-literal-suffix");
CheckFactories.registerCheck<UseAnyOfAllOfCheck>(
"readability-use-anyofallof");
+ CheckFactories.registerCheck<UseNumericLimitsCheck>(
+ "readability-use-numeric-limits");
CheckFactories.registerCheck<UseStdMinMaxCheck>(
"readability-use-std-min-max");
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
new file mode 100644
index 0000000000000..b26ae008cbdd5
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -0,0 +1,135 @@
+//===--- UseNumericLimitsCheck.cpp - clang-tidy ---------------------------===//
+//
+// 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 "UseNumericLimitsCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include <cmath>
+#include <limits>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+UseNumericLimitsCheck::UseNumericLimitsCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ SignedConstants{
+ {std::numeric_limits<int8_t>::min(),
+ "std::numeric_limits<int8_t>::min()"},
+ {std::numeric_limits<int8_t>::max(),
+ "std::numeric_limits<int8_t>::max()"},
+ {std::numeric_limits<int16_t>::min(),
+ "std::numeric_limits<int16_t>::min()"},
+ {std::numeric_limits<int16_t>::max(),
+ "std::numeric_limits<int16_t>::max()"},
+ {std::numeric_limits<int32_t>::min(),
+ "std::numeric_limits<int32_t>::min()"},
+ {std::numeric_limits<int32_t>::max(),
+ "std::numeric_limits<int32_t>::max()"},
+ {std::numeric_limits<int64_t>::min(),
+ "std::numeric_limits<int64_t>::min()"},
+ {std::numeric_limits<int64_t>::max(),
+ "std::numeric_limits<int64_t>::max()"},
+
+ },
+ UnsignedConstants{
+ {std::numeric_limits<uint8_t>::max(),
+ "std::numeric_limits<uint8_t>::max()"},
+ {std::numeric_limits<uint16_t>::max(),
+ "std::numeric_limits<uint16_t>::max()"},
+ {std::numeric_limits<uint32_t>::max(),
+ "std::numeric_limits<uint32_t>::max()"},
+ {std::numeric_limits<uint64_t>::max(),
+ "std::numeric_limits<uint64_t>::max()"},
+ },
+ Inserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void UseNumericLimitsCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ expr(anyOf(unaryOperator(hasOperatorName("-"),
+ hasUnaryOperand(integerLiteral().bind(
+ "negative-integer-literal"))),
+ unaryOperator(hasOperatorName("+"),
+ hasUnaryOperand(integerLiteral().bind(
+ "positive-integer-literal"))),
+ integerLiteral(unless(hasParent(unaryOperator(
+ hasAnyOperatorName("-", "+")))))
+ .bind("bare-integer-literal")))
+ .bind("unary-op-exp"),
+ this);
+}
+
+void UseNumericLimitsCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+ Inserter.registerPreprocessor(PP);
+}
+
+void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
+ const IntegerLiteral *MatchedDecl = nullptr;
+
+ const IntegerLiteral *NegativeMatchedDecl =
+ Result.Nodes.getNodeAs<IntegerLiteral>("negative-integer-literal");
+ const IntegerLiteral *PositiveMatchedDecl =
+ Result.Nodes.getNodeAs<IntegerLiteral>("positive-integer-literal");
+ const IntegerLiteral *BareMatchedDecl =
+ Result.Nodes.getNodeAs<IntegerLiteral>("bare-integer-literal");
+
+ if (NegativeMatchedDecl != nullptr) {
+ MatchedDecl = NegativeMatchedDecl;
+ } else if (PositiveMatchedDecl != nullptr) {
+ MatchedDecl = PositiveMatchedDecl;
+ } else if (BareMatchedDecl != nullptr) {
+ MatchedDecl = BareMatchedDecl;
+ }
+
+ // Only valid if unary operator is present
+ const UnaryOperator *UnaryOpExpr =
+ Result.Nodes.getNodeAs<UnaryOperator>("unary-op-exp");
+
+ const llvm::APInt MatchedIntegerConstant = MatchedDecl->getValue();
+ const auto Language = getLangOpts();
+
+ auto Fixer = [&](auto SourceValue, auto Value,
+ const std::string &Replacement) {
+ SourceLocation Location = MatchedDecl->getExprLoc();
+ SourceRange Range{MatchedDecl->getBeginLoc(), MatchedDecl->getEndLoc()};
+
+ if (MatchedDecl == NegativeMatchedDecl && -SourceValue == Value) {
+ Range = SourceRange(UnaryOpExpr->getBeginLoc(), UnaryOpExpr->getEndLoc());
+ Location = UnaryOpExpr->getExprLoc();
+ SourceValue = -SourceValue;
+ } else if (MatchedDecl == PositiveMatchedDecl && SourceValue == Value) {
+ Range = SourceRange(UnaryOpExpr->getBeginLoc(), UnaryOpExpr->getEndLoc());
+ Location = UnaryOpExpr->getExprLoc();
+ } else if (MatchedDecl != BareMatchedDecl || SourceValue != Value) {
+ return;
+ }
+
+ diag(Location, "The constant " + std::to_string(SourceValue) +
+ " is being utilized. "
+ "Consider using " +
+ Replacement + " instead")
+ << FixItHint::CreateReplacement(Range, Replacement)
+ << Inserter.createIncludeInsertion(
+ Result.SourceManager->getFileID(Location), "<limits>");
+ };
+
+ for (const auto &[Value, Replacement] : SignedConstants) {
+ Fixer(MatchedIntegerConstant.getSExtValue(), Value, Replacement);
+ }
+
+ for (const auto &[Value, Replacement] : UnsignedConstants) {
+ Fixer(MatchedIntegerConstant.getZExtValue(), Value, Replacement);
+ }
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
new file mode 100644
index 0000000000000..d7231132ef5dd
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
@@ -0,0 +1,41 @@
+//===--- UseNumericLimitsCheck.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_READABILITY_USENUMERICLIMITSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USENUMERICLIMITSCHECK_H
+
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
+#include <vector>
+
+namespace clang::tidy::readability {
+
+/// Replaces certain integer literals with equivalent calls to
+/// ``std::numeric_limits``.
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/use-numeric-limits.html
+class UseNumericLimitsCheck : public ClangTidyCheck {
+public:
+ UseNumericLimitsCheck(StringRef Name, ClangTidyContext *Context);
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus11;
+ }
+
+private:
+ const std::vector<std::tuple<int64_t, std::string>> SignedConstants;
+ const std::vector<std::tuple<uint64_t, std::string>> UnsignedConstants;
+ utils::IncludeInserter Inserter;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USENUMERICLIMITSCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6b8fe22242417..b2dfb0de6ae68 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -91,6 +91,11 @@ Improvements to clang-tidy
New checks
^^^^^^^^^^
+- New :doc:`readability-use-numeric-limits
+ <clang-tidy/checks/readability/use-numeric-limits>` check to replace certain
+ integer literals with ``std::numeric_limits`` calls.
+
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 7b9b905ef7671..e69ab96cf4bf9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -403,6 +403,7 @@ Clang-Tidy Checks
:doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes"
:doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`readability-use-anyofallof <readability/use-anyofallof>`,
+ :doc:`readability-use-numeric-limits <readability/use-numeric-limits>`, "Yes"
:doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
:doc:`zircon-temporary-objects <zircon/temporary-objects>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
new file mode 100644
index 0000000000000..ed50d00f1085d
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
@@ -0,0 +1,22 @@
+.. title:: clang-tidy - readability-use-numeric-limits
+
+readability-use-numeric-limits
+==============================
+
+Replaces certain integer literals with ``std::numeric_limits`` calls.
+
+Before:
+
+.. code-block:: c++
+
+ void foo() {
+ int32_t a = 2147483647;
+ }
+
+After:
+
+.. code-block:: c++
+
+ void foo() {
+ int32_t a = std::numeric_limits<int32_t>::max();
+ }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
new file mode 100644
index 0000000000000..2f1d5190148b0
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s readability-use-numeric-limits %t
+#include <stdint.h>
+
+void constants() {
+ // CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant -128 is being utilized. Consider using std::numeric_limits<int8_t>::min() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::min();
+ int8_t _ = -128;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant 127 is being utilized. Consider using std::numeric_limits<int8_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::max();
+ int8_t _ = +127;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant 127 is being utilized. Consider using std::numeric_limits<int8_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::max();
+ int8_t _ = 127;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -32768 is being utilized. Consider using std::numeric_limits<int16_t>::min() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::min();
+ int16_t _ = -32768;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 32767 is being utilized. Consider using std::numeric_limits<int16_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::max();
+ int16_t _ = +32767;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 32767 is being utilized. Consider using std::numeric_limits<int16_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::max();
+ int16_t _ = 32767;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -2147483648 is being utilized. Consider using std::numeric_limits<int32_t>::min() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::min();
+ int32_t _ = -2147483648;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 2147483647 is being utilized. Consider using std::numeric_limits<int32_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::max();
+ int32_t _ = +2147483647;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 2147483647 is being utilized. Consider using std::numeric_limits<int32_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::max();
+ int32_t _ = 2147483647;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -9223372036854775808 is being utilized. Consider using std::numeric_limits<int64_t>::min() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::min();
+ int64_t _ = -9223372036854775808;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 9223372036854775807 is being utilized. Consider using std::numeric_limits<int64_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::max();
+ int64_t _ = +9223372036854775807;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 9223372036854775807 is being utilized. Consider using std::numeric_limits<int64_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::max();
+ int64_t _ = 9223372036854775807;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 255 is being utilized. Consider using std::numeric_limits<uint8_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint8_t _ = std::numeric_limits<uint8_t>::max();
+ uint8_t _ = 255;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 255 is being utilized. Consider using std::numeric_limits<uint8_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint8_t _ = std::numeric_limits<uint8_t>::max();
+ uint8_t _ = +255;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 65535 is being utilized. Consider using std::numeric_limits<uint16_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint16_t _ = std::numeric_limits<uint16_t>::max();
+ uint16_t _ = 65535;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 65535 is being utilized. Consider using std::numeric_limits<uint16_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint16_t _ = std::numeric_limits<uint16_t>::max();
+ uint16_t _ = +65535;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 4294967295 is being utilized. Consider using std::numeric_limits<uint32_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint32_t _ = std::numeric_limits<uint32_t>::max();
+ uint32_t _ = 4294967295;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 4294967295 is being utilized. Consider using std::numeric_limits<uint32_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint32_t _ = std::numeric_limits<uint32_t>::max();
+ uint32_t _ = +4294967295;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 18446744073709551615 is being utilized. Consider using std::numeric_limits<uint64_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint64_t _ = std::numeric_limits<uint64_t>::max();
+ uint64_t _ = 18446744073709551615;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 18446744073709551615 is being utilized. Consider using std::numeric_limits<uint64_t>::max() instead [readability-use-numeric-limits]
+ // CHECK-FIXES: uint64_t _ = std::numeric_limits<uint64_t>::max();
+ uint64_t _ = +18446744073709551615;
+}
+
>From b649d723835e45df7788f2c0d9a8ad95179edd57 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Mon, 17 Feb 2025 11:07:31 -0500
Subject: [PATCH 02/10] Fix issues from code review
---
.../clang-tidy/readability/UseNumericLimitsCheck.cpp | 1 -
clang-tools-extra/docs/ReleaseNotes.rst | 6 ++++--
.../clang-tidy/checkers/readability/use-numeric-limits.cpp | 1 -
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index b26ae008cbdd5..7f14c0337ce18 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -96,7 +96,6 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
Result.Nodes.getNodeAs<UnaryOperator>("unary-op-exp");
const llvm::APInt MatchedIntegerConstant = MatchedDecl->getValue();
- const auto Language = getLangOpts();
auto Fixer = [&](auto SourceValue, auto Value,
const std::string &Replacement) {
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index b2dfb0de6ae68..4a0de02a8a77e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -92,8 +92,10 @@ New checks
^^^^^^^^^^
- New :doc:`readability-use-numeric-limits
- <clang-tidy/checks/readability/use-numeric-limits>` check to replace certain
- integer literals with ``std::numeric_limits`` calls.
+ <clang-tidy/checks/readability/use-numeric-limits>` check.
+
+ Replaces certain integer literals with equivalent calls to
+ ``std::numeric_limits<T>::min()`` or ``std::numeric_limits<T>::max()``.
New check aliases
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
index 2f1d5190148b0..9ad745c7c62c9 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
@@ -82,4 +82,3 @@ void constants() {
// CHECK-FIXES: uint64_t _ = std::numeric_limits<uint64_t>::max();
uint64_t _ = +18446744073709551615;
}
-
>From 15ded5eb660e6a2e9107cc4c1ddbaef6ccb8dd17 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Mon, 17 Feb 2025 11:16:27 -0500
Subject: [PATCH 03/10] Synchronize release note and docs
---
.../docs/clang-tidy/checks/readability/use-numeric-limits.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
index ed50d00f1085d..d24df618a3018 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
@@ -3,7 +3,8 @@
readability-use-numeric-limits
==============================
-Replaces certain integer literals with ``std::numeric_limits`` calls.
+ Replaces certain integer literals with equivalent calls to
+ ``std::numeric_limits<T>::min()`` or ``std::numeric_limits<T>::max()``.
Before:
>From fa054327530fdf019fc6272cc8011fa5e53970fe Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Tue, 18 Feb 2025 10:40:53 -0500
Subject: [PATCH 04/10] Fix small things
---
.../readability/UseNumericLimitsCheck.cpp | 15 ++--
.../readability/UseNumericLimitsCheck.h | 3 -
.../readability/use-numeric-limits.cpp | 82 +++++++++----------
3 files changed, 48 insertions(+), 52 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index 7f14c0337ce18..b2806138f12a2 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -91,10 +91,6 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
MatchedDecl = BareMatchedDecl;
}
- // Only valid if unary operator is present
- const UnaryOperator *UnaryOpExpr =
- Result.Nodes.getNodeAs<UnaryOperator>("unary-op-exp");
-
const llvm::APInt MatchedIntegerConstant = MatchedDecl->getValue();
auto Fixer = [&](auto SourceValue, auto Value,
@@ -102,6 +98,10 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation Location = MatchedDecl->getExprLoc();
SourceRange Range{MatchedDecl->getBeginLoc(), MatchedDecl->getEndLoc()};
+ // Only valid if unary operator is present
+ const UnaryOperator *UnaryOpExpr =
+ Result.Nodes.getNodeAs<UnaryOperator>("unary-op-exp");
+
if (MatchedDecl == NegativeMatchedDecl && -SourceValue == Value) {
Range = SourceRange(UnaryOpExpr->getBeginLoc(), UnaryOpExpr->getEndLoc());
Location = UnaryOpExpr->getExprLoc();
@@ -113,10 +113,9 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
return;
}
- diag(Location, "The constant " + std::to_string(SourceValue) +
- " is being utilized. "
- "Consider using " +
- Replacement + " instead")
+ diag(Location,
+ "The constant %0 is being utilized. Consider using %1 instead")
+ << std::to_string(SourceValue) << Replacement
<< FixItHint::CreateReplacement(Range, Replacement)
<< Inserter.createIncludeInsertion(
Result.SourceManager->getFileID(Location), "<limits>");
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
index d7231132ef5dd..cce45deda2394 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
@@ -26,9 +26,6 @@ class UseNumericLimitsCheck : public ClangTidyCheck {
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
- bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
- return LangOpts.CPlusPlus11;
- }
private:
const std::vector<std::tuple<int64_t, std::string>> SignedConstants;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
index 9ad745c7c62c9..8053332fc2dee 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
@@ -1,84 +1,84 @@
-// RUN: %check_clang_tidy -std=c++11-or-later %s readability-use-numeric-limits %t
+// RUN: %check_clang_tidy %s readability-use-numeric-limits %t
#include <stdint.h>
void constants() {
// CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant -128 is being utilized. Consider using std::numeric_limits<int8_t>::min() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::min();
- int8_t _ = -128;
+ // CHECK-FIXES: int8_t a = std::numeric_limits<int8_t>::min();
+ int8_t a = -128;
// CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant 127 is being utilized. Consider using std::numeric_limits<int8_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::max();
- int8_t _ = +127;
+ // CHECK-FIXES: int8_t b = std::numeric_limits<int8_t>::max();
+ int8_t b = +127;
// CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant 127 is being utilized. Consider using std::numeric_limits<int8_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int8_t _ = std::numeric_limits<int8_t>::max();
- int8_t _ = 127;
+ // CHECK-FIXES: int8_t c = std::numeric_limits<int8_t>::max();
+ int8_t c = 127;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -32768 is being utilized. Consider using std::numeric_limits<int16_t>::min() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::min();
- int16_t _ = -32768;
+ // CHECK-FIXES: int16_t d = std::numeric_limits<int16_t>::min();
+ int16_t d = -32768;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 32767 is being utilized. Consider using std::numeric_limits<int16_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::max();
- int16_t _ = +32767;
+ // CHECK-FIXES: int16_t e = std::numeric_limits<int16_t>::max();
+ int16_t e = +32767;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 32767 is being utilized. Consider using std::numeric_limits<int16_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int16_t _ = std::numeric_limits<int16_t>::max();
- int16_t _ = 32767;
+ // CHECK-FIXES: int16_t f = std::numeric_limits<int16_t>::max();
+ int16_t f = 32767;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -2147483648 is being utilized. Consider using std::numeric_limits<int32_t>::min() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::min();
- int32_t _ = -2147483648;
+ // CHECK-FIXES: int32_t g = std::numeric_limits<int32_t>::min();
+ int32_t g = -2147483648;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 2147483647 is being utilized. Consider using std::numeric_limits<int32_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::max();
- int32_t _ = +2147483647;
+ // CHECK-FIXES: int32_t h = std::numeric_limits<int32_t>::max();
+ int32_t h = +2147483647;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 2147483647 is being utilized. Consider using std::numeric_limits<int32_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int32_t _ = std::numeric_limits<int32_t>::max();
- int32_t _ = 2147483647;
+ // CHECK-FIXES: int32_t i = std::numeric_limits<int32_t>::max();
+ int32_t i = 2147483647;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant -9223372036854775808 is being utilized. Consider using std::numeric_limits<int64_t>::min() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::min();
- int64_t _ = -9223372036854775808;
+ // CHECK-FIXES: int64_t j = std::numeric_limits<int64_t>::min();
+ int64_t j = -9223372036854775808;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 9223372036854775807 is being utilized. Consider using std::numeric_limits<int64_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::max();
- int64_t _ = +9223372036854775807;
+ // CHECK-FIXES: int64_t k = std::numeric_limits<int64_t>::max();
+ int64_t k = +9223372036854775807;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 9223372036854775807 is being utilized. Consider using std::numeric_limits<int64_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: int64_t _ = std::numeric_limits<int64_t>::max();
- int64_t _ = 9223372036854775807;
+ // CHECK-FIXES: int64_t l = std::numeric_limits<int64_t>::max();
+ int64_t l = 9223372036854775807;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 255 is being utilized. Consider using std::numeric_limits<uint8_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint8_t _ = std::numeric_limits<uint8_t>::max();
- uint8_t _ = 255;
+ // CHECK-FIXES: uint8_t m = std::numeric_limits<uint8_t>::max();
+ uint8_t m = 255;
// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: The constant 255 is being utilized. Consider using std::numeric_limits<uint8_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint8_t _ = std::numeric_limits<uint8_t>::max();
- uint8_t _ = +255;
+ // CHECK-FIXES: uint8_t n = std::numeric_limits<uint8_t>::max();
+ uint8_t n = +255;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 65535 is being utilized. Consider using std::numeric_limits<uint16_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint16_t _ = std::numeric_limits<uint16_t>::max();
- uint16_t _ = 65535;
+ // CHECK-FIXES: uint16_t o = std::numeric_limits<uint16_t>::max();
+ uint16_t o = 65535;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 65535 is being utilized. Consider using std::numeric_limits<uint16_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint16_t _ = std::numeric_limits<uint16_t>::max();
- uint16_t _ = +65535;
+ // CHECK-FIXES: uint16_t p = std::numeric_limits<uint16_t>::max();
+ uint16_t p = +65535;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 4294967295 is being utilized. Consider using std::numeric_limits<uint32_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint32_t _ = std::numeric_limits<uint32_t>::max();
- uint32_t _ = 4294967295;
+ // CHECK-FIXES: uint32_t q = std::numeric_limits<uint32_t>::max();
+ uint32_t q = 4294967295;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 4294967295 is being utilized. Consider using std::numeric_limits<uint32_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint32_t _ = std::numeric_limits<uint32_t>::max();
- uint32_t _ = +4294967295;
+ // CHECK-FIXES: uint32_t r = std::numeric_limits<uint32_t>::max();
+ uint32_t r = +4294967295;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 18446744073709551615 is being utilized. Consider using std::numeric_limits<uint64_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint64_t _ = std::numeric_limits<uint64_t>::max();
- uint64_t _ = 18446744073709551615;
+ // CHECK-FIXES: uint64_t s = std::numeric_limits<uint64_t>::max();
+ uint64_t s = 18446744073709551615;
// CHECK-MESSAGES: :[[@LINE+2]]:16: warning: The constant 18446744073709551615 is being utilized. Consider using std::numeric_limits<uint64_t>::max() instead [readability-use-numeric-limits]
- // CHECK-FIXES: uint64_t _ = std::numeric_limits<uint64_t>::max();
- uint64_t _ = +18446744073709551615;
+ // CHECK-FIXES: uint64_t t = std::numeric_limits<uint64_t>::max();
+ uint64_t t = +18446744073709551615;
}
>From 261cfcb9dd4ab5b66018b943a76a1ffc8d6c35c3 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Tue, 18 Feb 2025 11:08:49 -0500
Subject: [PATCH 05/10] Store (and document) IncludeStyle option
---
.../clang-tidy/readability/UseNumericLimitsCheck.cpp | 4 ++++
.../clang-tidy/readability/UseNumericLimitsCheck.h | 1 +
.../clang-tidy/checks/readability/use-numeric-limits.rst | 8 ++++++++
3 files changed, 13 insertions(+)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index b2806138f12a2..ec9a74885c28b 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -53,6 +53,10 @@ UseNumericLimitsCheck::UseNumericLimitsCheck(StringRef Name,
utils::IncludeSorter::IS_LLVM),
areDiagsSelfContained()) {}
+void UseNumericLimitsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IncludeStyle", Inserter.getStyle());
+}
+
void UseNumericLimitsCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
expr(anyOf(unaryOperator(hasOperatorName("-"),
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
index cce45deda2394..c6fe568086014 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
@@ -22,6 +22,7 @@ namespace clang::tidy::readability {
class UseNumericLimitsCheck : public ClangTidyCheck {
public:
UseNumericLimitsCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
index d24df618a3018..0dfc29c4b95ae 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-numeric-limits.rst
@@ -21,3 +21,11 @@ After:
void foo() {
int32_t a = std::numeric_limits<int32_t>::max();
}
+
+Options
+-------
+
+.. option:: IncludeStyle
+
+ A string specifying which include-style is used, `llvm` or `google`. Default
+ is `llvm`.
>From 3c4a272496b70f6a3ce4fac0d818ec5da27d948c Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Tue, 18 Feb 2025 11:30:23 -0500
Subject: [PATCH 06/10] Explicitly match only against specific values
---
.../readability/UseNumericLimitsCheck.cpp | 51 ++++++++++++++-----
1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index ec9a74885c28b..0903e864b0959 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -58,18 +58,45 @@ void UseNumericLimitsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void UseNumericLimitsCheck::registerMatchers(MatchFinder *Finder) {
- Finder->addMatcher(
- expr(anyOf(unaryOperator(hasOperatorName("-"),
- hasUnaryOperand(integerLiteral().bind(
- "negative-integer-literal"))),
- unaryOperator(hasOperatorName("+"),
- hasUnaryOperand(integerLiteral().bind(
- "positive-integer-literal"))),
- integerLiteral(unless(hasParent(unaryOperator(
- hasAnyOperatorName("-", "+")))))
- .bind("bare-integer-literal")))
- .bind("unary-op-exp"),
- this);
+ auto PositiveIntegerMatcher = [](auto Value) {
+ return unaryOperator(
+ hasOperatorName("+"),
+ hasUnaryOperand(
+ integerLiteral(equals(Value)).bind("positive-integer-literal")));
+ };
+
+ auto NegativeIntegerMatcher = [](auto Value) {
+ return unaryOperator(
+ hasOperatorName("-"),
+ hasUnaryOperand(
+ integerLiteral(equals(-Value)).bind("negative-integer-literal")));
+ };
+
+ auto BareIntegerMatcher = [](auto Value) {
+ return integerLiteral(allOf(unless(hasParent(unaryOperator(
+ hasAnyOperatorName("-", "+")))),
+ equals(Value)))
+ .bind("bare-integer-literal");
+ };
+
+ for (const auto &[Value, _] : SignedConstants) {
+ if (Value < 0) {
+ Finder->addMatcher(
+ expr(NegativeIntegerMatcher(Value)).bind("unary-op-exp"), this);
+ } else {
+ Finder->addMatcher(
+ expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value)))
+ .bind("unary-op-exp"),
+ this);
+ }
+ }
+
+ for (const auto &[Value, _] : UnsignedConstants) {
+ Finder->addMatcher(
+ expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value)))
+ .bind("unary-op-exp"),
+ this);
+ }
}
void UseNumericLimitsCheck::registerPPCallbacks(
>From 01452a15489b65d955bc257ed50b03ed9cfb2646 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Fri, 21 Feb 2025 14:26:17 -0500
Subject: [PATCH 07/10] Fix small comments
---
.../clang-tidy/readability/UseNumericLimitsCheck.cpp | 1 -
.../clang-tidy/readability/UseNumericLimitsCheck.h | 5 ++---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index 0903e864b0959..d2203ea579a9e 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -37,7 +37,6 @@ UseNumericLimitsCheck::UseNumericLimitsCheck(StringRef Name,
"std::numeric_limits<int64_t>::min()"},
{std::numeric_limits<int64_t>::max(),
"std::numeric_limits<int64_t>::max()"},
-
},
UnsignedConstants{
{std::numeric_limits<uint8_t>::max(),
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
index c6fe568086014..62fb181258ae4 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.h
@@ -11,7 +11,6 @@
#include "../ClangTidyCheck.h"
#include "../utils/IncludeInserter.h"
-#include <vector>
namespace clang::tidy::readability {
@@ -29,8 +28,8 @@ class UseNumericLimitsCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
- const std::vector<std::tuple<int64_t, std::string>> SignedConstants;
- const std::vector<std::tuple<uint64_t, std::string>> UnsignedConstants;
+ const llvm::SmallVector<std::pair<int64_t, std::string>> SignedConstants;
+ const llvm::SmallVector<std::pair<uint64_t, std::string>> UnsignedConstants;
utils::IncludeInserter Inserter;
};
>From be01b74029e13477f246cedceb1cc44d15090910 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Fri, 28 Feb 2025 11:02:58 -0500
Subject: [PATCH 08/10] Bind unary-op only in the required matchers
---
.../readability/UseNumericLimitsCheck.cpp | 27 +++++++++----------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index d2203ea579a9e..0f666392b9442 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -58,17 +58,17 @@ void UseNumericLimitsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void UseNumericLimitsCheck::registerMatchers(MatchFinder *Finder) {
auto PositiveIntegerMatcher = [](auto Value) {
- return unaryOperator(
- hasOperatorName("+"),
- hasUnaryOperand(
- integerLiteral(equals(Value)).bind("positive-integer-literal")));
+ return unaryOperator(hasOperatorName("+"),
+ hasUnaryOperand(integerLiteral(equals(Value))
+ .bind("positive-integer-literal")))
+ .bind("unary-op");
};
auto NegativeIntegerMatcher = [](auto Value) {
- return unaryOperator(
- hasOperatorName("-"),
- hasUnaryOperand(
- integerLiteral(equals(-Value)).bind("negative-integer-literal")));
+ return unaryOperator(hasOperatorName("-"),
+ hasUnaryOperand(integerLiteral(equals(-Value))
+ .bind("negative-integer-literal")))
+ .bind("unary-op");
};
auto BareIntegerMatcher = [](auto Value) {
@@ -80,20 +80,17 @@ void UseNumericLimitsCheck::registerMatchers(MatchFinder *Finder) {
for (const auto &[Value, _] : SignedConstants) {
if (Value < 0) {
- Finder->addMatcher(
- expr(NegativeIntegerMatcher(Value)).bind("unary-op-exp"), this);
+ Finder->addMatcher(NegativeIntegerMatcher(Value), this);
} else {
Finder->addMatcher(
- expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value)))
- .bind("unary-op-exp"),
+ expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value))),
this);
}
}
for (const auto &[Value, _] : UnsignedConstants) {
Finder->addMatcher(
- expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value)))
- .bind("unary-op-exp"),
+ expr(anyOf(PositiveIntegerMatcher(Value), BareIntegerMatcher(Value))),
this);
}
}
@@ -130,7 +127,7 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
// Only valid if unary operator is present
const UnaryOperator *UnaryOpExpr =
- Result.Nodes.getNodeAs<UnaryOperator>("unary-op-exp");
+ Result.Nodes.getNodeAs<UnaryOperator>("unary-op");
if (MatchedDecl == NegativeMatchedDecl && -SourceValue == Value) {
Range = SourceRange(UnaryOpExpr->getBeginLoc(), UnaryOpExpr->getEndLoc());
>From f3460537fb599bef5a9a157bd25d9c6afcc07f86 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Fri, 28 Feb 2025 11:31:19 -0500
Subject: [PATCH 09/10] Add Valid checks
---
.../checkers/readability/use-numeric-limits.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
index 8053332fc2dee..794dfcea00a52 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-numeric-limits.cpp
@@ -1,7 +1,7 @@
// RUN: %check_clang_tidy %s readability-use-numeric-limits %t
#include <stdint.h>
-void constants() {
+void Invalid() {
// CHECK-MESSAGES: :[[@LINE+2]]:14: warning: The constant -128 is being utilized. Consider using std::numeric_limits<int8_t>::min() instead [readability-use-numeric-limits]
// CHECK-FIXES: int8_t a = std::numeric_limits<int8_t>::min();
int8_t a = -128;
@@ -82,3 +82,9 @@ void constants() {
// CHECK-FIXES: uint64_t t = std::numeric_limits<uint64_t>::max();
uint64_t t = +18446744073709551615;
}
+
+void Valid(){
+ int16_t a = +128;
+
+ int16_t b = -127;
+}
>From b790ab1aafb22e784a06ca4faf75bd91c357f346 Mon Sep 17 00:00:00 2001
From: Katherine Whitlock <kate at skylinesynths.nyc>
Date: Fri, 28 Feb 2025 11:34:42 -0500
Subject: [PATCH 10/10] Fail compilation if the SourceValue and Value are not
the same types
---
.../clang-tidy/readability/UseNumericLimitsCheck.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
index 0f666392b9442..b263d12738ce2 100644
--- a/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseNumericLimitsCheck.cpp
@@ -122,6 +122,9 @@ void UseNumericLimitsCheck::check(const MatchFinder::MatchResult &Result) {
auto Fixer = [&](auto SourceValue, auto Value,
const std::string &Replacement) {
+ static_assert(std::is_same_v<decltype(SourceValue), decltype(Value)>,
+ "The types of SourceValue and Value must match");
+
SourceLocation Location = MatchedDecl->getExprLoc();
SourceRange Range{MatchedDecl->getBeginLoc(), MatchedDecl->getEndLoc()};
More information about the cfe-commits
mailing list