1// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true}}" --
2
3class 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
10int X;
11extern int A[10];
12extern short B[10];
13
14#pragma pack(1)
15struct S { char a, b, c; };
16
17enum E { E_VALUE = 0 };
18enum class EC { VALUE = 0 };
19
20bool AsBool() { return false; }
21int AsInt() { return 0; }
22E AsEnum() { return E_VALUE; }
23EC AsEnumClass() { return EC::VALUE; }
24S AsStruct() { return {}; }
25
26struct M {
27 int AsInt() { return 0; }
28 E AsEnum() { return E_VALUE; }
29 S AsStruct() { return {}; }
30};
31
32int ReturnOverload(int) { return {}; }
33S ReturnOverload(S) { return {}; }
34
35template <class T>
36T ReturnTemplate(T) { return {}; }
37
38template <class T>
39bool TestTrait1() {
40 return sizeof(ReturnOverload(T{})) == sizeof(A);
41}
42
43template <class T>
44bool TestTrait2() {
45 return sizeof(ReturnTemplate(T{})) == sizeof(A);
46}
47
48template <class T>
49bool 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
54template <class T>
55bool 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
60bool 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
73int 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
144typedef char MyChar;
145typedef const MyChar MyConstChar;
146
147int CE0 = sizeof sizeof(char);
148// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
149int CE1 = sizeof +sizeof(char);
150// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
151int CE2 = sizeof sizeof(const char*);
152// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
153int CE3 = sizeof sizeof(const volatile char* const*);
154// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
155int CE4 = sizeof sizeof(MyConstChar);
156// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
157
158int 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
169template <int T>
170int Foo() { int A[T]; return sizeof(T); }
171// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'
172template <typename T>
173int 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)'
175int Test3() { return Foo<42>() + Bar<char>(); }
176
177static const char* kABC = "abc";
178static const wchar_t* kDEF = L"def";
179int 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
188int 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
258int 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__
288template <__int128_t N>
289#else
290template <long N> // Fallback for platforms which do not define `__int128_t`
291#endif
292bool Baz() { return sizeof(A) < N; }
293// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant
294bool Test7() { return Baz<-1>(); }
295
296int 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

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp