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