1 | // RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true}}" -- |
2 | |
3 | class C { |
4 | int size() { return sizeof(this); } |
5 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)' |
6 | }; |
7 | |
8 | #define LEN 8 |
9 | |
10 | int X; |
11 | extern int A[10]; |
12 | extern short B[10]; |
13 | |
14 | #pragma pack(1) |
15 | struct S { char a, b, c; }; |
16 | |
17 | enum E { E_VALUE = 0 }; |
18 | enum class EC { VALUE = 0 }; |
19 | |
20 | bool AsBool() { return false; } |
21 | int AsInt() { return 0; } |
22 | E AsEnum() { return E_VALUE; } |
23 | EC AsEnumClass() { return EC::VALUE; } |
24 | S AsStruct() { return {}; } |
25 | |
26 | struct M { |
27 | int AsInt() { return 0; } |
28 | E AsEnum() { return E_VALUE; } |
29 | S AsStruct() { return {}; } |
30 | }; |
31 | |
32 | int ReturnOverload(int) { return {}; } |
33 | S ReturnOverload(S) { return {}; } |
34 | |
35 | template <class T> |
36 | T ReturnTemplate(T) { return {}; } |
37 | |
38 | template <class T> |
39 | bool TestTrait1() { |
40 | return sizeof(ReturnOverload(T{})) == sizeof(A); |
41 | } |
42 | |
43 | template <class T> |
44 | bool TestTrait2() { |
45 | return sizeof(ReturnTemplate(T{})) == sizeof(A); |
46 | } |
47 | |
48 | template <class T> |
49 | bool TestTrait3() { |
50 | return sizeof(ReturnOverload(0)) == sizeof(T{}); |
51 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
52 | } |
53 | |
54 | template <class T> |
55 | bool TestTrait4() { |
56 | return sizeof(ReturnTemplate(0)) == sizeof(T{}); |
57 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
58 | } |
59 | |
60 | bool TestTemplates() { |
61 | bool b = true; |
62 | b &= TestTrait1<int>(); |
63 | b &= TestTrait1<S>(); |
64 | b &= TestTrait2<int>(); |
65 | b &= TestTrait2<S>(); |
66 | b &= TestTrait3<int>(); |
67 | b &= TestTrait3<S>(); |
68 | b &= TestTrait4<int>(); |
69 | b &= TestTrait4<S>(); |
70 | return b; |
71 | } |
72 | |
73 | int Test1(const char* ptr) { |
74 | int sum = 0; |
75 | sum += sizeof(LEN); |
76 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' |
77 | sum += sizeof(LEN + 1); |
78 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' |
79 | sum += sizeof(sum, LEN); |
80 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)' |
81 | sum += sizeof(AsBool()); |
82 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
83 | sum += sizeof(AsInt()); |
84 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
85 | sum += sizeof(AsEnum()); |
86 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
87 | sum += sizeof(AsEnumClass()); |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
89 | sum += sizeof(M{}.AsInt()); |
90 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
91 | sum += sizeof(M{}.AsEnum()); |
92 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer |
93 | sum += sizeof(sizeof(X)); |
94 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
95 | sum += sizeof(LEN + sizeof(X)); |
96 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
97 | sum += sizeof(LEN + LEN + sizeof(X)); |
98 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
99 | sum += sizeof(LEN + (LEN + sizeof(X))); |
100 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
101 | sum += sizeof(LEN + -sizeof(X)); |
102 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
103 | sum += sizeof(LEN + - + -sizeof(X)); |
104 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' |
105 | sum += sizeof(char) / sizeof(char); |
106 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
107 | sum += sizeof(A) / sizeof(S); |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator |
109 | sum += sizeof(char) / sizeof(int); |
110 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator |
111 | sum += sizeof(char) / sizeof(A); |
112 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator |
113 | sum += sizeof(B[0]) / sizeof(A); |
114 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator |
115 | sum += sizeof(ptr) / sizeof(char); |
116 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' |
117 | sum += sizeof(ptr) / sizeof(ptr[0]); |
118 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' |
119 | sum += sizeof(ptr) / sizeof(char*); |
120 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)' |
121 | sum += sizeof(ptr) / sizeof(void*); |
122 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)' |
123 | sum += sizeof(ptr) / sizeof(const void volatile*); |
124 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)' |
125 | sum += sizeof(ptr) / sizeof(char); |
126 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' |
127 | sum += sizeof(ptr) / sizeof(ptr[0]); |
128 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)' |
129 | sum += sizeof(int) * sizeof(char); |
130 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication |
131 | sum += sizeof(ptr) * sizeof(ptr[0]); |
132 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication |
133 | sum += sizeof(int) * (2 * sizeof(char)); |
134 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication |
135 | sum += (2 * sizeof(char)) * sizeof(int); |
136 | // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication |
137 | if (sizeof(A) < 0x100000) sum += 42; |
138 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant |
139 | if (sizeof(A) <= 0xFFFFFFFEU) sum += 42; |
140 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant |
141 | return sum; |
142 | } |
143 | |
144 | typedef char MyChar; |
145 | typedef const MyChar MyConstChar; |
146 | |
147 | int CE0 = sizeof sizeof(char); |
148 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' |
149 | int CE1 = sizeof +sizeof(char); |
150 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' |
151 | int CE2 = sizeof sizeof(const char*); |
152 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' |
153 | int CE3 = sizeof sizeof(const volatile char* const*); |
154 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' |
155 | int CE4 = sizeof sizeof(MyConstChar); |
156 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' |
157 | |
158 | int Test2(MyConstChar* A) { |
159 | int sum = 0; |
160 | sum += sizeof(MyConstChar) / sizeof(char); |
161 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
162 | sum += sizeof(MyConstChar) / sizeof(MyChar); |
163 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
164 | sum += sizeof(A[0]) / sizeof(char); |
165 | // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
166 | return sum; |
167 | } |
168 | |
169 | template <int T> |
170 | int Foo() { int A[T]; return sizeof(T); } |
171 | // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)' |
172 | template <typename T> |
173 | int Bar() { T A[5]; return sizeof(A[0]) / sizeof(T); } |
174 | // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
175 | int Test3() { return Foo<42>() + Bar<char>(); } |
176 | |
177 | static const char* kABC = "abc" ; |
178 | static const wchar_t* kDEF = L"def" ; |
179 | int Test4(const char A[10]) { |
180 | int sum = 0; |
181 | sum += sizeof(kABC); |
182 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)' |
183 | sum += sizeof(kDEF); |
184 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)' |
185 | return sum; |
186 | } |
187 | |
188 | int Test5() { |
189 | typedef int Array10[10]; |
190 | typedef C ArrayC[10]; |
191 | |
192 | struct MyStruct { |
193 | Array10 arr; |
194 | Array10* ptr; |
195 | }; |
196 | typedef const MyStruct TMyStruct; |
197 | typedef const MyStruct *PMyStruct; |
198 | typedef TMyStruct *PMyStruct2; |
199 | |
200 | static TMyStruct kGlocalMyStruct = {}; |
201 | static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct; |
202 | |
203 | MyStruct S; |
204 | PMyStruct PS; |
205 | PMyStruct2 PS2; |
206 | Array10 A10; |
207 | C *PtrArray[10]; |
208 | C *PC; |
209 | |
210 | int sum = 0; |
211 | sum += sizeof(&S.arr); |
212 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
213 | sum += sizeof(&kGlocalMyStruct.arr); |
214 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
215 | sum += sizeof(&kGlocalMyStructPtr->arr); |
216 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
217 | sum += sizeof(S.arr + 0); |
218 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
219 | sum += sizeof(+ S.arr); |
220 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
221 | sum += sizeof((int*)S.arr); |
222 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
223 | |
224 | sum += sizeof(S.ptr); |
225 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
226 | sum += sizeof(kGlocalMyStruct.ptr); |
227 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
228 | sum += sizeof(kGlocalMyStructPtr->ptr); |
229 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
230 | |
231 | sum += sizeof(&kGlocalMyStruct); |
232 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
233 | sum += sizeof(&S); |
234 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
235 | sum += sizeof(MyStruct*); |
236 | sum += sizeof(PMyStruct); |
237 | sum += sizeof(PS); |
238 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
239 | sum += sizeof(PS2); |
240 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
241 | sum += sizeof(&A10); |
242 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
243 | sum += sizeof(PtrArray) / sizeof(PtrArray[1]); |
244 | // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
245 | sum += sizeof(A10) / sizeof(PtrArray[0]); |
246 | // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
247 | sum += sizeof(PC) / sizeof(PtrArray[0]); |
248 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
249 | // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)' |
250 | // CHECK-MESSAGES: :[[@LINE-3]]:23: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
251 | sum += sizeof(ArrayC) / sizeof(PtrArray[0]); |
252 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator |
253 | // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate |
254 | |
255 | return sum; |
256 | } |
257 | |
258 | int Test6() { |
259 | int sum = 0; |
260 | |
261 | struct S A = AsStruct(), B = AsStruct(); |
262 | struct S *P = &A, *Q = &B; |
263 | sum += sizeof(struct S) == P - Q; |
264 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
265 | sum += 5 * sizeof(S) != P - Q; |
266 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
267 | sum += sizeof(S) < P - Q; |
268 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
269 | sum += 5 * sizeof(S) <= P - Q; |
270 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
271 | sum += 5 * sizeof(*P) >= P - Q; |
272 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
273 | sum += Q - P > 3 * sizeof(*P); |
274 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
275 | sum += sizeof(S) + (P - Q); |
276 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
277 | sum += 5 * sizeof(S) - (P - Q); |
278 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
279 | sum += (P - Q) / sizeof(S); |
280 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
281 | sum += (P - Q) / sizeof(*Q); |
282 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic |
283 | |
284 | return sum; |
285 | } |
286 | |
287 | #ifdef __SIZEOF_INT128__ |
288 | template <__int128_t N> |
289 | #else |
290 | template <long N> // Fallback for platforms which do not define `__int128_t` |
291 | #endif |
292 | bool Baz() { return sizeof(A) < N; } |
293 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant |
294 | bool Test7() { return Baz<-1>(); } |
295 | |
296 | int ValidExpressions() { |
297 | int A[] = {1, 2, 3, 4}; |
298 | static const char str[] = "hello" ; |
299 | static const char* ptr[] { "aaa" , "bbb" , "ccc" }; |
300 | typedef C *CA10[10]; |
301 | C *PtrArray[10]; |
302 | CA10 PtrArray1; |
303 | |
304 | int sum = 0; |
305 | if (sizeof(A) < 10) |
306 | sum += sizeof(A); |
307 | sum += sizeof(int); |
308 | sum += sizeof(AsStruct()); |
309 | sum += sizeof(M{}.AsStruct()); |
310 | sum += sizeof(A[sizeof(A) / sizeof(int)]); |
311 | sum += sizeof(&A[sizeof(A) / sizeof(int)]); |
312 | sum += sizeof(sizeof(0)); // Special case: sizeof size_t. |
313 | sum += sizeof(void*); |
314 | sum += sizeof(void const *); |
315 | sum += sizeof(void const *) / 4; |
316 | sum += sizeof(str); |
317 | sum += sizeof(str) / sizeof(char); |
318 | sum += sizeof(str) / sizeof(str[0]); |
319 | sum += sizeof(ptr) / sizeof(ptr[0]); |
320 | sum += sizeof(ptr) / sizeof(*(ptr)); |
321 | sum += sizeof(PtrArray) / sizeof(PtrArray[0]); |
322 | // Canonical type of PtrArray1 is same as PtrArray. |
323 | sum = sizeof(PtrArray) / sizeof(PtrArray1[0]); |
324 | // There is no warning for 'sizeof(T*)/sizeof(Q)' case. |
325 | sum += sizeof(PtrArray) / sizeof(A[0]); |
326 | return sum; |
327 | } |
328 | |