[clang-tools-extra] 556600a - [clang-tidy] Add option to ignore user-defined literals in readability-magic-numbers

Carlos Galvez via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 26 09:43:11 PDT 2023


Author: Carlos Galvez
Date: 2023-03-26T16:41:17Z
New Revision: 556600af6a8a7f241277f7a22c3e3746e7b09123

URL: https://github.com/llvm/llvm-project/commit/556600af6a8a7f241277f7a22c3e3746e7b09123
DIFF: https://github.com/llvm/llvm-project/commit/556600af6a8a7f241277f7a22c3e3746e7b09123.diff

LOG: [clang-tidy] Add option to ignore user-defined literals in readability-magic-numbers

Some user-defined literals operate on implementation-defined types, like
"unsigned long long" and "long double", which are not well supported by
this check. Currently, the check gives warnings when using UDLs, without
giving possiblity to the user to whitelist common UDLs. A good compromise
until a proper fix is found (if any) is to allow the user to disable
warnings on UDLs.

Partially fixes #61656

Differential Revision: https://reviews.llvm.org/D146913

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
    clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/docs/clang-tidy/checks/readability/magic-numbers.rst
    clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers-userliteral.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
index ca81b6e3c6e61..cffe858c39ad1 100644
--- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -81,6 +81,8 @@ MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
       IgnorePowersOf2IntegerValues(
           Options.get("IgnorePowersOf2IntegerValues", false)),
       IgnoreTypeAliases(Options.get("IgnoreTypeAliases", false)),
+      IgnoreUserDefinedLiterals(
+          Options.get("IgnoreUserDefinedLiterals", false)),
       RawIgnoredIntegerValues(
           Options.get("IgnoredIntegerValues", DefaultIgnoredIntegerValues)),
       RawIgnoredFloatingPointValues(Options.get(
@@ -130,6 +132,7 @@ void MagicNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "IgnorePowersOf2IntegerValues",
                 IgnorePowersOf2IntegerValues);
   Options.store(Opts, "IgnoreTypeAliases", IgnoreTypeAliases);
+  Options.store(Opts, "IgnoreUserDefinedLiterals", IgnoreUserDefinedLiterals);
   Options.store(Opts, "IgnoredIntegerValues", RawIgnoredIntegerValues);
   Options.store(Opts, "IgnoredFloatingPointValues",
                 RawIgnoredFloatingPointValues);
@@ -243,5 +246,14 @@ bool MagicNumbersCheck::isBitFieldWidth(
                       });
 }
 
+bool MagicNumbersCheck::isUserDefinedLiteral(
+    const clang::ast_matchers::MatchFinder::MatchResult &Result,
+    const clang::Expr &Literal) const {
+  DynTypedNodeList Parents = Result.Context->getParents(Literal);
+  if (Parents.empty())
+    return false;
+  return Parents[0].get<UserDefinedLiteral>() != nullptr;
+}
+
 } // namespace tidy::readability
 } // namespace clang

diff  --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
index 39e9baea3adc8..79787845de619 100644
--- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
@@ -49,6 +49,10 @@ class MagicNumbersCheck : public ClangTidyCheck {
   bool isBitFieldWidth(const clang::ast_matchers::MatchFinder::MatchResult &Result,
                        const IntegerLiteral &Literal) const;
 
+  bool isUserDefinedLiteral(
+      const clang::ast_matchers::MatchFinder::MatchResult &Result,
+      const clang::Expr &Literal) const;
+
   template <typename L>
   void checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result,
                        const char *BoundName) {
@@ -72,6 +76,10 @@ class MagicNumbersCheck : public ClangTidyCheck {
     if (isBitFieldWidth(Result, *MatchedLiteral))
       return;
 
+    if (IgnoreUserDefinedLiterals &&
+        isUserDefinedLiteral(Result, *MatchedLiteral))
+      return;
+
     const StringRef LiteralSourceText = Lexer::getSourceText(
         CharSourceRange::getTokenRange(MatchedLiteral->getSourceRange()),
         *Result.SourceManager, getLangOpts());
@@ -85,6 +93,7 @@ class MagicNumbersCheck : public ClangTidyCheck {
   const bool IgnoreBitFieldsWidths;
   const bool IgnorePowersOf2IntegerValues;
   const bool IgnoreTypeAliases;
+  const bool IgnoreUserDefinedLiterals;
   const StringRef RawIgnoredIntegerValues;
   const StringRef RawIgnoredFloatingPointValues;
 

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 1a53aac8fecf4..03ba9e160b738 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -223,6 +223,9 @@ Changes in existing checks
   behavior of using `i` as the prefix for enum tags, set the `EnumConstantPrefix`
   option to `i` instead of using `EnumConstantHungarianPrefix`.
 
+- Added support to optionally ignore user-defined literals in
+  :doc:`readability-magic-numbers<clang-tidy/checks/readability/magic-numbers>`.
+
 - Fixed a false positive in :doc:`readability-container-size-empty
   <clang-tidy/checks/readability/container-size-empty>` check when comparing
   ``std::array`` objects to default constructed ones. The behavior for this and

diff  --git a/clang-tools-extra/docs/clang-tidy/checks/readability/magic-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/magic-numbers.rst
index b5017f81d0a59..4b3d7190d4345 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/magic-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/magic-numbers.rst
@@ -57,7 +57,7 @@ Example with magic values refactored:
 
    const size_t NUMBER_OF_ELEMENTS = 30;
    using containerType = CustomType<int, NUMBER_OF_ELEMENTS>;
-   
+
    struct OtherType {
       containerType container;
    }
@@ -144,3 +144,8 @@ Options
 
    Boolean value indicating whether to accept magic numbers in ``typedef`` or
    ``using`` declarations. Default value is `false`.
+
+.. option:: IgnoreUserDefinedLiterals
+
+   Boolean value indicating whether to accept magic numbers in user-defined
+   literals. Default value is `false`.

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers-userliteral.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers-userliteral.cpp
index 82c4d7b0afced..12ce9cbc9476e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers-userliteral.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers-userliteral.cpp
@@ -1,10 +1,18 @@
-// RUN: %check_clang_tidy -std=c++14-or-later %s readability-magic-numbers %t --
+// RUN: %check_clang_tidy -check-suffixes=UDL-ALLOWED -std=c++14-or-later %s readability-magic-numbers %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: readability-magic-numbers.IgnoreUserDefinedLiterals, value: false}]}' \
+// RUN: --
+// RUN: %check_clang_tidy -check-suffixes=UDL-IGNORED -std=c++14-or-later %s readability-magic-numbers %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: readability-magic-numbers.IgnoreUserDefinedLiterals, value: true}]}' \
+// RUN: --
 
 namespace std {
   class string {};
   using size_t = decltype(sizeof(int));
   string operator ""s(const char *, std::size_t);
   int operator "" s(unsigned long long);
+  float operator "" s(long double);
 }
 
 void UserDefinedLiteral() {
@@ -12,5 +20,9 @@ void UserDefinedLiteral() {
   "Hello World"s;
   const int i = 3600s;
   int j = 3600s;
-  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 3600s is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+  // CHECK-MESSAGES-UDL-ALLOWED: :[[@LINE-1]]:11: warning: 3600s is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+  // CHECK-MESSAGES-UDL-IGNORED-NOT: :[[@LINE-2]]:11: warning: 3600s is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+  float k = 3600.0s;
+  // CHECK-MESSAGES-UDL-ALLOWED: :[[@LINE-1]]:13: warning: 3600.0s is a magic number; consider replacing it with a named constant [readability-magic-numbers]
+  // CHECK-MESSAGES-UDL-IGNORED-NOT: :[[@LINE-1]]:13: warning: 3600.0s is a magic number; consider replacing it with a named constant [readability-magic-numbers]
 }


        


More information about the cfe-commits mailing list