1 // RUN: %check_clang_tidy %s readability-magic-numbers %t \
2 // RUN: -config='{CheckOptions: \
3 // RUN:  [{key: readability-magic-numbers.IgnoredIntegerValues, value: "0;1;2;10;100;"}, \
4 // RUN:   {key: readability-magic-numbers.IgnoredFloatingPointValues, value: "3.14;2.71828;9.81;10000.0;101.0;0x1.2p3"}, \
5 // RUN:   {key: readability-magic-numbers.IgnorePowersOf2IntegerValues, value: 1}]}' \
6 // RUN: --
7 
8 template <typename T, int V>
9 struct ValueBucket {
10   T value[V];
11 };
12 
13 int BadGlobalInt = 5;
14 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
15 
IntSquarer(int param)16 int IntSquarer(int param) {
17   return param * param;
18 }
19 
BuggyFunction()20 void BuggyFunction() {
21   int BadLocalInt = 6;
22   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
23 
24   (void)IntSquarer(7);
25   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 7 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
26 
27   int LocalArray[15];
28   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 15 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
29 
30   for (int ii = 0; ii < 22; ++ii)
31   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 22 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
32   {
33     LocalArray[ii] = 3 * ii;
34     // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
35   }
36 
37   ValueBucket<int, 66> Bucket;
38   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 66 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
39 }
40 
41 class TwoIntContainer {
42 public:
TwoIntContainer(int val)43   TwoIntContainer(int val) : anotherMember(val * val), yetAnotherMember(6), anotherConstant(val + val) {}
44   // CHECK-MESSAGES: :[[@LINE-1]]:73: warning: 6 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
45 
46   int getValue() const;
47 
48 private:
49   int oneMember = 9;
50   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: 9 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
51 
52   int anotherMember;
53 
54   int yetAnotherMember;
55 
56   const int oneConstant = 2;
57 
58   const int anotherConstant;
59 };
60 
61 int ValueArray[] = {3, 5};
62 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
63 // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: 5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
64 
65 float FloatPiVariable = 3.1415926535f;
66 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 3.1415926535f is a magic number; consider replacing it with a named constant [readability-magic-numbers]
67 double DoublePiVariable = 6.283185307;
68 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 6.283185307 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
69 
70 float SomeFloats[] = {0.5, 0x1.2p4};
71 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 0.5 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
72 // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: 0x1.2p4 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
73 
getAnswer()74 int getAnswer() {
75   if (ValueArray[0] < ValueArray[1])
76     return ValueArray[1];
77 
78   return -3; // FILENOTFOUND
79   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 3 is a magic number; consider replacing it with a named constant [readability-magic-numbers]
80 }
81 
82 /*
83  * Clean code
84  */
85 
86 #define INT_MACRO 5
87 
88 const int GoodGlobalIntConstant = 42;
89 
90 constexpr int AlsoGoodGlobalIntConstant = 42;
91 
92 int InitializedByMacro = INT_MACRO;
93 
SolidFunction()94 void SolidFunction() {
95   const int GoodLocalIntConstant = 43;
96 
97   (void)IntSquarer(GoodLocalIntConstant);
98 
99   int LocalArray[INT_MACRO];
100 
101   ValueBucket<int, INT_MACRO> Bucket;
102 }
103 
104 const int ConstValueArray[] = {7, 9};
105 
106 const int ConstValueArray2D[2][2] = {{7, 9}, {13, 15}};
107 
108 /*
109  * no warnings for ignored values (specified in the configuration above)
110  */
111 int GrandfatheredIntegerValues[] = {0, 1, 2, 10, 100, -1, -10, -100, 65536};
112 
113 float GrandfatheredFloatValues[] = {3.14f, 3.14, 2.71828, 2.71828f, -1.01E2, 1E4, 0x1.2p3};
114 
115 /*
116  * no warnings for enums
117  */
118 enum Smorgasbord {
119   STARTER,
120   ALPHA = 3,
121   BETA = 1 << 5,
122 };
123 
124 const float FloatPiConstant = 3.1415926535f;
125 const double DoublePiConstant = 6.283185307;
126 
127 const float Angles[] = {45.0f, 90.0f, 135.0f};
128 
129 double DoubleZeroIsAccepted = 0.0;
130 float FloatZeroIsAccepted = 0.0f;
131 
132 namespace geometry {
133 
134 template <typename T>
135 struct Point {
136   T x;
137   T y;
138 
Pointgeometry::Point139   explicit Point(T xval, T yval) noexcept : x{xval}, y{yval} {
140   }
141 };
142 
143 template <typename T>
144 struct Dimension {
145   T x;
146   T y;
147 
Dimensiongeometry::Dimension148   explicit Dimension(T xval, T yval) noexcept : x{xval}, y{yval} {
149   }
150 };
151 
152 template <typename T>
153 struct Rectangle {
154   Point<T> origin;
155   Dimension<T> size;
156   T rotation; // angle of rotation around origin
157 
Rectanglegeometry::Rectangle158   Rectangle(Point<T> origin_, Dimension<T> size_, T rotation_ = 0) noexcept : origin{origin_}, size{size_}, rotation{rotation_} {
159   }
160 
161   bool contains(Point<T> point) const;
162 };
163 
164 } // namespace geometry
165 
166 const geometry::Rectangle<double> mandelbrotCanvas{geometry::Point<double>{-2.5, -1}, geometry::Dimension<double>{3.5, 2}};
167 
168 // Simulate the macro magic in Google Test internal headers
169 class AssertionHelper {
170 public:
AssertionHelper(const char * Message,int LineNumber)171   AssertionHelper(const char *Message, int LineNumber) : Message(Message), LineNumber(LineNumber) {}
172 
173 private:
174   const char *Message;
175   int LineNumber;
176 };
177 
178 #define ASSERTION_HELPER_AT(M, L) AssertionHelper(M, L)
179 
180 #define ASSERTION_HELPER(M) ASSERTION_HELPER_AT(M, __LINE__)
181 
FunctionWithCompilerDefinedSymbol(void)182 void FunctionWithCompilerDefinedSymbol(void) {
183   ASSERTION_HELPER("here and now");
184 }
185 
186 // prove that integer literals introduced by the compiler are accepted silently
187 extern int ConsumeString(const char *Input);
188 
189 const char *SomeStrings[] = {"alpha", "beta", "gamma"};
190 
TestCheckerOverreach()191 int TestCheckerOverreach() {
192   int Total = 0;
193 
194   for (const auto *Str : SomeStrings) {
195     Total += ConsumeString(Str);
196   }
197 
198   return Total;
199 }
200