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 <k...@skylinesynths.nyc> Date: Sun, 16 Feb 2025 22:45:06 -0500 Subject: [PATCH 1/6] [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 <k...@skylinesynths.nyc> Date: Mon, 17 Feb 2025 11:07:31 -0500 Subject: [PATCH 2/6] 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 <k...@skylinesynths.nyc> Date: Mon, 17 Feb 2025 11:16:27 -0500 Subject: [PATCH 3/6] 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 <k...@skylinesynths.nyc> Date: Tue, 18 Feb 2025 10:40:53 -0500 Subject: [PATCH 4/6] 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 <k...@skylinesynths.nyc> Date: Tue, 18 Feb 2025 11:08:49 -0500 Subject: [PATCH 5/6] 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 <k...@skylinesynths.nyc> Date: Tue, 18 Feb 2025 11:30:23 -0500 Subject: [PATCH 6/6] 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( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits