IdrissRio updated this revision to Diff 168321.
IdrissRio added a comment.
Herald added a subscriber: jfb.

Sorry i have forgot to add the source code.


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,76 @@
+// RUN: %check_clang_tidy %s readability-numerical-costants-to-max-int %t
+unsigned const int Uval1 = -1;
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: Add '#include<limits>' to use std::numeric_limits<type>::max() function [readability-numerical-costants-to-max-int]
+// CHECK-MESSAGES: :[[@LINE-2]]: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;
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,36 @@
+.. title:: clang-tidy - readability-numerical-costants-to-max-int
+
+readability-numerical-costants-to-max-int
+==================================
+
+
+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 it adds the library 'limits'.
+
+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();
+  
\ 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
@@ -9,8 +9,8 @@
    abseil-no-internal-dependencies
    abseil-no-namespace
    abseil-redundant-strcat-calls
-   abseil-string-find-startswith
    abseil-str-cat-append
+   abseil-string-find-startswith
    android-cloexec-accept
    android-cloexec-accept4
    android-cloexec-creat
@@ -216,6 +216,7 @@
    performance-unnecessary-copy-initialization
    performance-unnecessary-value-param
    portability-simd-intrinsics
+   readability-NumericalCostantsToMaxInt
    readability-avoid-const-params-in-decls
    readability-braces-around-statements
    readability-container-size-empty
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,12 @@
 Improvements to clang-tidy
 --------------------------
 
+- 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().
+
 - New :doc:`abseil-duration-division
   <clang-tidy/checks/abseil-duration-division>` check.
 
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,41 @@
+//===--- 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"
+
+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 it adds the library 'limits'.
+///
+class NumericalCostantsToMaxIntCheck : public ClangTidyCheck {
+public:
+  NumericalCostantsToMaxIntCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+
+private:
+  bool InsertLimits;
+  SourceLocation IncludeLocation;
+};
+
+} // 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,125 @@
+//===--- 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 {
+
+namespace {
+class NumericalConstCheckPPCallbacks : public PPCallbacks {
+public:
+  explicit NumericalConstCheckPPCallbacks(bool &IL, SourceLocation *IS);
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported,
+                          SrcMgr::CharacteristicKind FileType) override;
+
+private:
+  bool *IL;
+  bool AtLeastOneInclude;
+  SourceLocation *IS;
+};
+} // namespace
+
+void NumericalConstCheckPPCallbacks::InclusionDirective(
+    SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
+    bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
+    StringRef SearchPath, StringRef RelativePath, const Module *Imported,
+    SrcMgr::CharacteristicKind FileType) {
+
+  if (FileName == "limits") {
+    *IL = true;
+    return;
+  }
+  if (AtLeastOneInclude)
+    return;
+
+  *IS = HashLoc;
+  AtLeastOneInclude = true;
+}
+
+NumericalConstCheckPPCallbacks::NumericalConstCheckPPCallbacks(
+    bool &IL, SourceLocation *IS)
+    : IL(&IL), AtLeastOneInclude(false), IS(IS){};
+
+void NumericalCostantsToMaxIntCheck::registerPPCallbacks(
+    CompilerInstance &Compiler) {
+  if (this->getLangOpts().CPlusPlus) {
+    Compiler.getPreprocessor().addPPCallbacks(
+        ::llvm::make_unique<NumericalConstCheckPPCallbacks>(InsertLimits,
+                                                            &IncludeLocation));
+  }
+}
+
+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("Lit"))))),
+                hasInitializer(ignoringImpCasts(unaryOperator(
+                    hasOperatorName("~"),
+                    hasUnaryOperand(integerLiteral(equals(0)).bind("Lit")))))))
+          .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>("Lit");
+  if (Decl == nullptr || Lit == nullptr)
+    return;
+
+  SourceManager *SM = Result.SourceManager;
+  std::string InsteadOf = "-1";
+  std::string Replacement =
+      ("std::numeric_limits<" +
+       StringRef(Decl->getType().getAtomicUnqualifiedType().getAsString()) +
+       ">::max()")
+          .str();
+
+  if (Lit->getValue() == 0)
+    InsteadOf = "~0";
+
+  diag(Lit->getLocation(), "use '%0' instead of '%1' for unsigned constant int")
+      << Replacement << InsteadOf
+      << FixItHint::CreateReplacement(
+             SourceRange(Lit->getBeginLoc().getLocWithOffset(-1),
+                         Lit->getEndLoc()),
+             Replacement);
+
+  if (InsertLimits)
+    return;
+
+  if (IncludeLocation.isInvalid())
+    IncludeLocation =
+        SM->getLocForStartOfFile(SM->getFileID(Lit->getBeginLoc()));
+
+  diag(IncludeLocation, "Add '#include<limits>' to use "
+                        "std::numeric_limits<type>::max() function")
+      << FixItHint::CreateInsertion(IncludeLocation, "#include <limits>\n");
+}
+
+} // 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