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