bruntib created this revision.
bruntib added reviewers: alexfh, Szelethus, 0x8000-0000, aaron.ballman.
Herald added subscribers: cfe-commits, xazax.hun, whisperity.
Herald added a project: clang.

The following code snippet results a false positive report in the magic number 
checker:

std::string s = "Hello World"s;

The expression "Hello World"s has a StringLiteral in its AST, since this is a 
function call on std::string operator "" s(const char* std::size_t) and the 
second parameter is passed the length of the string literal.

This patch fixes https://bugs.llvm.org/show_bug.cgi?id=40633


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D67265

Files:
  clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
  clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp


Index: clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
+++ clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-magic-numbers %t \
+// RUN: %check_clang_tidy -std=c++14 %s readability-magic-numbers %t \
 // RUN: -config='{CheckOptions: \
 // RUN:  [{key: readability-magic-numbers.IgnoredIntegerValues, value: 
"0;1;2;10;100;"}, \
 // RUN:   {key: readability-magic-numbers.IgnoredFloatingPointValues, value: 
"3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \
@@ -197,3 +197,18 @@
 
   return Total;
 }
+
+namespace std {
+  class string {};
+  using size_t = decltype(sizeof(int));
+  string operator "" s(const char *, std::size_t);
+  int operator "" s(unsigned long long);
+}
+
+void UserDefinedLiteral() {
+  using std::operator ""s;
+  "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]
+}
Index: clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -112,10 +112,21 @@
   return llvm::any_of(
       Result.Context->getParents(ExprResult),
       [&Result](const DynTypedNode &Parent) {
-        return isUsedToInitializeAConstant(Result, Parent) ||
-               // Ignore this instance, because this match reports the location
-               // where the template is defined, not where it is instantiated.
-               Parent.get<SubstNonTypeTemplateParmExpr>();
+        if (isUsedToInitializeAConstant(Result, Parent))
+          return true;
+
+        // Ignore this instance, because this match reports the location
+        // where the template is defined, not where it is instantiated.
+        if (Parent.get<SubstNonTypeTemplateParmExpr>())
+          return true;
+
+        // Don't warn on string user defined literals:
+        // std::string s = "Hello World"s;
+        if (const UserDefinedLiteral *UDL = Parent.get<UserDefinedLiteral>())
+          if (UDL->getLiteralOperatorKind() == UserDefinedLiteral::LOK_String)
+            return true;
+
+        return false;
       });
 }
 


Index: clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
+++ clang-tools-extra/test/clang-tidy/readability-magic-numbers.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s readability-magic-numbers %t \
+// RUN: %check_clang_tidy -std=c++14 %s readability-magic-numbers %t \
 // RUN: -config='{CheckOptions: \
 // RUN:  [{key: readability-magic-numbers.IgnoredIntegerValues, value: "0;1;2;10;100;"}, \
 // RUN:   {key: readability-magic-numbers.IgnoredFloatingPointValues, value: "3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \
@@ -197,3 +197,18 @@
 
   return Total;
 }
+
+namespace std {
+  class string {};
+  using size_t = decltype(sizeof(int));
+  string operator "" s(const char *, std::size_t);
+  int operator "" s(unsigned long long);
+}
+
+void UserDefinedLiteral() {
+  using std::operator ""s;
+  "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]
+}
Index: clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -112,10 +112,21 @@
   return llvm::any_of(
       Result.Context->getParents(ExprResult),
       [&Result](const DynTypedNode &Parent) {
-        return isUsedToInitializeAConstant(Result, Parent) ||
-               // Ignore this instance, because this match reports the location
-               // where the template is defined, not where it is instantiated.
-               Parent.get<SubstNonTypeTemplateParmExpr>();
+        if (isUsedToInitializeAConstant(Result, Parent))
+          return true;
+
+        // Ignore this instance, because this match reports the location
+        // where the template is defined, not where it is instantiated.
+        if (Parent.get<SubstNonTypeTemplateParmExpr>())
+          return true;
+
+        // Don't warn on string user defined literals:
+        // std::string s = "Hello World"s;
+        if (const UserDefinedLiteral *UDL = Parent.get<UserDefinedLiteral>())
+          if (UDL->getLiteralOperatorKind() == UserDefinedLiteral::LOK_String)
+            return true;
+
+        return false;
       });
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to