xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability/magic-numbers.cpp (revision e8a3ddafe063c970df9c23e803812369abde4c82)
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 
IntSquarer(int param)18 int IntSquarer(int param) {
19   return param * param;
20 }
21 
BuggyFunction()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(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:
TwoIntContainer(int val)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 
getAnswer()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 
SolidFunction()117 void SolidFunction() {
118   const int GoodLocalIntConstant = 43;
119 
120   (void)IntSquarer(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 
Pointgeometry::Point162   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 
Dimensiongeometry::Dimension171   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 
Rectanglegeometry::Rectangle181   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:
AssertionHelper(const char * Message,int LineNumber)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 
FunctionWithCompilerDefinedSymbol(void)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 
TestCheckerOverreach()214 int TestCheckerOverreach() {
215   int Total = 0;
216 
217   for (const auto *Str : SomeStrings) {
218     Total += ConsumeString(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