IdrissRio updated this revision to Diff 168662.
IdrissRio marked 22 inline comments as done.
IdrissRio edited the summary of this revision.
IdrissRio added a comment.

Update with the suggestion proposed by @Eugene.Zelenko and @JonasToth


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D52892

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/NumericalCostantsToMaxIntCheck.cpp
  clang-tidy/readability/NumericalCostantsToMaxIntCheck.h
  clang-tidy/readability/ReadabilityTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-numerical-costants-to-max-int.rst
  test/clang-tidy/readability-numerical-costants-to-max-int.cpp

Index: test/clang-tidy/readability-numerical-costants-to-max-int.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-numerical-costants-to-max-int.cpp
@@ -0,0 +1,120 @@
+// RUN: %check_clang_tidy %s readability-numerical-costants-to-max-int %t
+unsigned const int Uval1 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: #include <limits>
+// CHECK-FIXES: unsigned const int Uval1 = std::numeric_limits<unsigned int>::max();
+
+unsigned const long Uval2 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use 'std::numeric_limits<unsigned long>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long Uval2 = std::numeric_limits<unsigned long>::max();
+
+unsigned const long int Uval3 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use 'std::numeric_limits<unsigned long>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long int Uval3 = std::numeric_limits<unsigned long>::max();
+
+unsigned const long long int Uval4 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use 'std::numeric_limits<unsigned long long>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long long int Uval4 = std::numeric_limits<unsigned long long>::max();
+
+unsigned const short int Uval5 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use 'std::numeric_limits<unsigned short>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const short int Uval5 = std::numeric_limits<unsigned short>::max();
+
+unsigned const Uval6 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const Uval6 = std::numeric_limits<unsigned int>::max();
+
+unsigned const char Uval7 = -1;
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use 'std::numeric_limits<unsigned char>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const char Uval7 = std::numeric_limits<unsigned char>::max();
+
+//if not constants do nothing
+unsigned int Uval8 = -1;
+unsigned long Uval9 = -1;
+unsigned long int Uval10 = -1;
+unsigned long long int Uval11 = -1;
+unsigned short int Uval12 = -1;
+unsigned Uval13 = -1;
+unsigned char Uval14 = -1;
+
+unsigned const long Uval15 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use 'std::numeric_limits<unsigned long>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long Uval15 = std::numeric_limits<unsigned long>::max();
+
+unsigned const long int Uval16 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use 'std::numeric_limits<unsigned long>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long int Uval16 = std::numeric_limits<unsigned long>::max();
+
+unsigned const long long int Uval17 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: use 'std::numeric_limits<unsigned long long>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const long long int Uval17 = std::numeric_limits<unsigned long long>::max();
+
+unsigned const short int Uval18 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: use 'std::numeric_limits<unsigned short>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const short int Uval18 = std::numeric_limits<unsigned short>::max();
+
+unsigned const Uval19 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const Uval19 = std::numeric_limits<unsigned int>::max();
+
+unsigned const char Uval20 = ~0;
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use 'std::numeric_limits<unsigned char>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+// CHECK-FIXES: unsigned const char Uval20 = std::numeric_limits<unsigned char>::max();
+
+//if not constants do nothing
+unsigned int Uval21 = ~0;
+unsigned long Uva22 = ~0;
+unsigned long int Uval23 = ~0;
+unsigned long long int Uval24 = ~0;
+unsigned short int Uval25 = ~0;
+unsigned Uval26 = ~0;
+unsigned char Uval27 = ~0;
+
+#define UNSIGNED unsigned
+#define CONST const
+#define UNSIGNEDCONST unsigned const
+#define UNSIGNEDCONSTDECLMINUS unsigned const x1 = -1;
+// CHECK-FIXES: #define UNSIGNEDCONSTDECLMINUS unsigned const x1 = std::numeric_limits<unsigned int>::max();
+
+#define UNSIGNEDCONSTDECLBITWISE unsigned const x2 = ~0;
+// CHECK-FIXES: #define UNSIGNEDCONSTDECLBITWISE unsigned const x2 = std::numeric_limits<unsigned int>::max();
+
+#define MINUSONE -1;
+// CHECK-FIXES: #define MINUSONE std::numeric_limits<unsigned int>::max();
+
+#define BITWISEZERO ~0;
+// CHECK-FIXES: #define BITWISEZERO std::numeric_limits<unsigned int>::max();
+template <typename Foo>
+void f() {
+  Foo f = -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+  // CHECK-FIXES: Foo f = std::numeric_limits<unsigned int>::max();
+}
+
+void testFunction() {
+  f<const unsigned>();
+
+  const UNSIGNED int y = -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+  // CHECK-FIXES: const UNSIGNED int y = std::numeric_limits<unsigned int>::max();
+
+  UNSIGNED CONST z = -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+  // CHECK-FIXES: UNSIGNED CONST z = std::numeric_limits<unsigned int>::max();
+
+  UNSIGNEDCONST w = -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+  // CHECK-FIXES: UNSIGNEDCONST w = std::numeric_limits<unsigned int>::max();
+
+  UNSIGNEDCONSTDECLMINUS
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+
+  UNSIGNEDCONSTDECLBITWISE
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+
+  UNSIGNEDCONST int a = MINUSONE;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '-1' for unsigned constant int [readability-numerical-costants-to-max-int]
+
+  UNSIGNEDCONST int b = BITWISEZERO;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use 'std::numeric_limits<unsigned int>::max()' instead of '~0' for unsigned constant int [readability-numerical-costants-to-max-int]
+}
Index: docs/clang-tidy/checks/readability-numerical-costants-to-max-int.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/readability-numerical-costants-to-max-int.rst
@@ -0,0 +1,44 @@
+.. title:: clang-tidy - readability-numerical-costants-to-max-int
+
+readability-numerical-costants-to-max-int
+=========================================
+
+
+Checks for numerical unsigned constants that are equal to '-1' or '~0'
+and substitutes them with 'std::numeric_limits<type>::max()'.
+
+If necessary adds the header file 'limits' of the standard library.
+
+Examples:
+
+.. code-block:: c++
+
+  unsigned const long int x = -1;
+
+becomes
+
+.. code-block:: c++
+
+  unsigned const long int x = std::numeric_limits<unsigned long>::max();
+
+or
+
+.. code-block:: c++
+
+  unsigned const short x = ~0;
+
+
+becomes
+
+.. code-block:: c++
+
+  unsigned const short x = std::numeric_limits<short>::max();
+
+  
+Options
+-------
+
+.. option:: IncludeStyle
+
+   A string specifying which include-style is used, `llvm` or `google`. Default
+   is `llvm`.
\ No newline at end of file
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -232,6 +232,7 @@
    readability-misplaced-array-index
    readability-named-parameter
    readability-non-const-parameter
+   readability-numerical-costants-to-max-int
    readability-redundant-control-flow
    readability-redundant-declaration
    readability-redundant-function-ptr-dereference
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -111,6 +111,12 @@
 
   Detects usage of magic numbers, numbers that are used as literals instead of
   introduced via constants or symbols.
+  
+- New :doc:`readability-numerical-costants-to-max-int
+  <clang-tidy/checks/readability-numerical-costants-to-max-int>` check.
+
+  Checks for numerical unsigned constants that are equal to '-1' or '~0'
+  and substitutes them with 'std::numeric_limits<type>::max()'.
 
 Improvements to include-fixer
 -----------------------------
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -25,6 +25,7 @@
 #include "MisplacedArrayIndexCheck.h"
 #include "NamedParameterCheck.h"
 #include "NonConstParameterCheck.h"
+#include "NumericalCostantsToMaxIntCheck.h"
 #include "RedundantControlFlowCheck.h"
 #include "RedundantDeclarationCheck.h"
 #include "RedundantFunctionPtrDereferenceCheck.h"
@@ -72,6 +73,8 @@
         "readability-misleading-indentation");
     CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
         "readability-misplaced-array-index");
+    CheckFactories.registerCheck<NumericalCostantsToMaxIntCheck>(
+        "readability-numerical-costants-to-max-int");
     CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
         "readability-redundant-function-ptr-dereference");
     CheckFactories.registerCheck<RedundantMemberInitCheck>(
Index: clang-tidy/readability/NumericalCostantsToMaxIntCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/readability/NumericalCostantsToMaxIntCheck.h
@@ -0,0 +1,42 @@
+//===--- NumericalCostantsToMaxIntCheck.h - clang-tidy ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NUMERICALCOSTANTSTOMAXINTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NUMERICALCOSTANTSTOMAXINTCHECK_H
+
+#include "../ClangTidy.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// \brief This check looks for numerical unsigned constants that are equal to
+/// -1 or ~0 and substitutes them with std::numeric_limits<type>::max().
+///
+/// If necessary adds the header file 'limits' of the standard library.
+///
+class NumericalCostantsToMaxIntCheck : public ClangTidyCheck {
+public:
+  NumericalCostantsToMaxIntCheck(StringRef Name, ClangTidyContext *Context);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+private:
+  const utils::IncludeSorter::IncludeStyle IncludeStyle;
+  std::unique_ptr<utils::IncludeInserter> Inserter;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NUMERICALCOSTANTSTOMAXINTCHECK_H
Index: clang-tidy/readability/NumericalCostantsToMaxIntCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/readability/NumericalCostantsToMaxIntCheck.cpp
@@ -0,0 +1,88 @@
+//===--- NumericalcostantstomaxintCheck.cpp - clang-tidy ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NumericalCostantsToMaxIntCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void NumericalCostantsToMaxIntCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IncludeStyle", IncludeStyle);
+}
+
+NumericalCostantsToMaxIntCheck::NumericalCostantsToMaxIntCheck(
+    StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      IncludeStyle(utils::IncludeSorter::parseIncludeStyle(
+          Options.getLocalOrGlobal("IncludeStyle", "llvm"))) {}
+
+void NumericalCostantsToMaxIntCheck::registerPPCallbacks(
+    CompilerInstance &Compiler) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  Inserter.reset(new utils::IncludeInserter(
+      Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle));
+  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+}
+
+void NumericalCostantsToMaxIntCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+  Finder->addMatcher(
+      varDecl(hasType(qualType(allOf(isUnsignedInteger(), isConstQualified()))),
+              anyOf(hasInitializer(ignoringImpCasts(unaryOperator(
+                        hasOperatorName("-"),
+                        hasUnaryOperand(
+                            integerLiteral(equals(1)).bind("Literal"))))),
+                    hasInitializer(ignoringImpCasts(unaryOperator(
+                        hasOperatorName("~"),
+                        hasUnaryOperand(
+                            integerLiteral(equals(0)).bind("Literal")))))))
+          .bind("VarDecl"),
+      this);
+}
+
+void NumericalCostantsToMaxIntCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("VarDecl");
+  const auto *Lit = Result.Nodes.getNodeAs<IntegerLiteral>("Literal");
+  assert(Decl != nullptr);
+  std::string InsteadOf = "-1";
+  std::string Replacement =
+      (Twine("std::numeric_limits<") +
+       Decl->getType().getAtomicUnqualifiedType().getAsString() + ">::max()")
+          .str();
+  if (Lit->getValue() == 0)
+    InsteadOf = "~0";
+  const SourceManager *SM = Result.SourceManager;
+  SourceRange LitSR =
+      SourceRange(SM->getSpellingLoc(Lit->getBeginLoc().getLocWithOffset(-1)),
+                  SM->getSpellingLoc(Lit->getEndLoc()));
+  auto Diag = diag(Lit->getLocation(),
+                   "use '%0' instead of '%1' for unsigned constant int")
+              << Replacement << InsteadOf
+              << FixItHint::CreateReplacement(LitSR, Replacement);
+
+  Optional<FixItHint> Insertion = Inserter->CreateIncludeInsertion(
+      Result.SourceManager->getMainFileID(), "limits", true);
+  if (Insertion)
+    Diag << Insertion.getValue();
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -17,6 +17,7 @@
   NamedParameterCheck.cpp
   NamespaceCommentCheck.cpp
   NonConstParameterCheck.cpp
+  NumericalCostantsToMaxIntCheck.cpp
   ReadabilityTidyModule.cpp
   RedundantControlFlowCheck.cpp
   RedundantDeclarationCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to