1546c816aSDonát Nagy // RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true, bugprone-sizeof-expression.WarnOnSizeOfPointer: true}}" --
2546c816aSDonát Nagy
3546c816aSDonát Nagy class C {
size()4546c816aSDonát Nagy int size() { return sizeof(this); }
5546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)'
6546c816aSDonát Nagy };
7546c816aSDonát Nagy
8546c816aSDonát Nagy #define LEN 8
9546c816aSDonát Nagy
10546c816aSDonát Nagy int X;
11546c816aSDonát Nagy extern int A[10];
12546c816aSDonát Nagy extern short B[10];
13546c816aSDonát Nagy
14546c816aSDonát Nagy #pragma pack(1)
15546c816aSDonát Nagy struct S { char a, b, c; };
16546c816aSDonát Nagy
17546c816aSDonát Nagy enum E { E_VALUE = 0 };
18546c816aSDonát Nagy enum class EC { VALUE = 0 };
19546c816aSDonát Nagy
AsBool()20546c816aSDonát Nagy bool AsBool() { return false; }
AsInt()21546c816aSDonát Nagy int AsInt() { return 0; }
AsEnum()22546c816aSDonát Nagy E AsEnum() { return E_VALUE; }
AsEnumClass()23546c816aSDonát Nagy EC AsEnumClass() { return EC::VALUE; }
AsStruct()24546c816aSDonát Nagy S AsStruct() { return {}; }
25546c816aSDonát Nagy
26546c816aSDonát Nagy struct M {
AsIntM27546c816aSDonát Nagy int AsInt() { return 0; }
AsEnumM28546c816aSDonát Nagy E AsEnum() { return E_VALUE; }
AsStructM29546c816aSDonát Nagy S AsStruct() { return {}; }
30546c816aSDonát Nagy };
31546c816aSDonát Nagy
Test1(const char * ptr)32546c816aSDonát Nagy int Test1(const char* ptr) {
33546c816aSDonát Nagy int sum = 0;
34546c816aSDonát Nagy sum += sizeof(LEN);
35546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
36546c816aSDonát Nagy sum += sizeof(LEN + 1);
37546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
38546c816aSDonát Nagy sum += sizeof(sum, LEN);
39546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)'
40546c816aSDonát Nagy sum += sizeof(AsBool());
41*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
42546c816aSDonát Nagy sum += sizeof(AsInt());
43*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
44546c816aSDonát Nagy sum += sizeof(AsEnum());
45*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
46546c816aSDonát Nagy sum += sizeof(AsEnumClass());
47*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
48546c816aSDonát Nagy sum += sizeof(M{}.AsInt());
49*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
50546c816aSDonát Nagy sum += sizeof(M{}.AsEnum());
51*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type
52546c816aSDonát Nagy sum += sizeof(sizeof(X));
53546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
54546c816aSDonát Nagy sum += sizeof(LEN + sizeof(X));
55546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
56546c816aSDonát Nagy sum += sizeof(LEN + LEN + sizeof(X));
57546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
58546c816aSDonát Nagy sum += sizeof(LEN + (LEN + sizeof(X)));
59546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
60546c816aSDonát Nagy sum += sizeof(LEN + -sizeof(X));
61546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
62546c816aSDonát Nagy sum += sizeof(LEN + - + -sizeof(X));
63546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
64546c816aSDonát Nagy sum += sizeof(char) / sizeof(char);
65*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type
66546c816aSDonát Nagy sum += sizeof(A) / sizeof(S);
67546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
68546c816aSDonát Nagy sum += sizeof(char) / sizeof(int);
69546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
70546c816aSDonát Nagy sum += sizeof(char) / sizeof(A);
71546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
72546c816aSDonát Nagy sum += sizeof(B[0]) / sizeof(A);
73546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
74546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(char);
75*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
76546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(ptr[0]);
77*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
78546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(char*);
79*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
80546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(void*);
81*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
82546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(const void volatile*);
83*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
84546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(char);
85*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
86546c816aSDonát Nagy sum += sizeof(int) * sizeof(char);
87546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
88546c816aSDonát Nagy sum += sizeof(ptr) * sizeof(ptr[0]);
89*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
90546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
91546c816aSDonát Nagy sum += sizeof(int) * (2 * sizeof(char));
92546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication
93546c816aSDonát Nagy sum += (2 * sizeof(char)) * sizeof(int);
94546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication
95546c816aSDonát Nagy if (sizeof(A) < 0x100000) sum += 42;
96546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant
97546c816aSDonát Nagy if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;
98546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant
99546c816aSDonát Nagy return sum;
100546c816aSDonát Nagy }
101546c816aSDonát Nagy
Test5()102546c816aSDonát Nagy int Test5() {
103546c816aSDonát Nagy typedef int Array10[10];
104546c816aSDonát Nagy typedef C ArrayC[10];
105546c816aSDonát Nagy
106546c816aSDonát Nagy struct MyStruct {
107546c816aSDonát Nagy Array10 arr;
108546c816aSDonát Nagy Array10* ptr;
109546c816aSDonát Nagy };
110546c816aSDonát Nagy typedef const MyStruct TMyStruct;
111546c816aSDonát Nagy typedef const MyStruct *PMyStruct;
112546c816aSDonát Nagy typedef TMyStruct *PMyStruct2;
113546c816aSDonát Nagy
114546c816aSDonát Nagy static TMyStruct kGlocalMyStruct = {};
115546c816aSDonát Nagy static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;
116546c816aSDonát Nagy
117546c816aSDonát Nagy MyStruct S;
118546c816aSDonát Nagy PMyStruct PS;
119546c816aSDonát Nagy PMyStruct2 PS2;
120546c816aSDonát Nagy Array10 A10;
121546c816aSDonát Nagy C *PtrArray[10];
122546c816aSDonát Nagy C *PC;
123546c816aSDonát Nagy
124546c816aSDonát Nagy char *PChar;
125546c816aSDonát Nagy int *PInt, **PPInt;
126546c816aSDonát Nagy MyStruct **PPMyStruct;
127546c816aSDonát Nagy
128546c816aSDonát Nagy int sum = 0;
129546c816aSDonát Nagy sum += sizeof(&S.arr);
130*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
131546c816aSDonát Nagy sum += sizeof(&kGlocalMyStruct.arr);
132*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
133546c816aSDonát Nagy sum += sizeof(&kGlocalMyStructPtr->arr);
134*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
135546c816aSDonát Nagy sum += sizeof(S.arr + 0);
136*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
137546c816aSDonát Nagy sum += sizeof(+ S.arr);
138*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
139546c816aSDonát Nagy sum += sizeof((int*)S.arr);
140*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
141546c816aSDonát Nagy
142546c816aSDonát Nagy sum += sizeof(S.ptr);
143*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
144546c816aSDonát Nagy sum += sizeof(kGlocalMyStruct.ptr);
145*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
146546c816aSDonát Nagy sum += sizeof(kGlocalMyStructPtr->ptr);
147*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
148546c816aSDonát Nagy
149546c816aSDonát Nagy sum += sizeof(&kGlocalMyStruct);
150*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
151546c816aSDonát Nagy sum += sizeof(&S);
152*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
153546c816aSDonát Nagy sum += sizeof(MyStruct*);
154546c816aSDonát Nagy sum += sizeof(PMyStruct);
155546c816aSDonát Nagy sum += sizeof(PS);
156*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
157546c816aSDonát Nagy sum += sizeof(PS2);
158*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
159546c816aSDonát Nagy sum += sizeof(&A10);
160*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
161546c816aSDonát Nagy sum += sizeof(PtrArray) / sizeof(PtrArray[1]);
162*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression of pointer type
163546c816aSDonát Nagy sum += sizeof(A10) / sizeof(PtrArray[0]);
164546c816aSDonát Nagy sum += sizeof(PC) / sizeof(PtrArray[0]);
165*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
166*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type
167546c816aSDonát Nagy sum += sizeof(ArrayC) / sizeof(PtrArray[0]);
168546c816aSDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
169546c816aSDonát Nagy
170546c816aSDonát Nagy sum += sizeof(PChar);
171*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
172546c816aSDonát Nagy sum += sizeof(PInt);
173*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
174546c816aSDonát Nagy sum += sizeof(PPInt);
175*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
176546c816aSDonát Nagy sum += sizeof(PPMyStruct);
177*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
178546c816aSDonát Nagy
179546c816aSDonát Nagy return sum;
180546c816aSDonát Nagy }
181546c816aSDonát Nagy
182546c816aSDonát Nagy void some_generic_function(const void *arg, int argsize);
183546c816aSDonát Nagy int *IntP, **IntPP;
184546c816aSDonát Nagy C *ClassP, **ClassPP;
185546c816aSDonát Nagy
GenericFunctionTest()186546c816aSDonát Nagy void GenericFunctionTest() {
187546c816aSDonát Nagy // The `sizeof(pointer)` checks ignore situations where the pointer is
188546c816aSDonát Nagy // produced by dereferencing a pointer-to-pointer, because this is unlikely
189546c816aSDonát Nagy // to be an accident and can appear in legitimate code that tries to call
190546c816aSDonát Nagy // a generic function which emulates dynamic typing within C.
191546c816aSDonát Nagy some_generic_function(IntPP, sizeof(*IntPP));
192546c816aSDonát Nagy some_generic_function(ClassPP, sizeof(*ClassPP));
193546c816aSDonát Nagy // Using `...[0]` instead of the dereference operator is another common
194546c816aSDonát Nagy // variant, which is also widespread in the idiomatic array-size calculation:
195546c816aSDonát Nagy // `sizeof(array) / sizeof(array[0])`.
196546c816aSDonát Nagy some_generic_function(IntPP, sizeof(IntPP[0]));
197546c816aSDonát Nagy some_generic_function(ClassPP, sizeof(ClassPP[0]));
198546c816aSDonát Nagy // FIXME: There is a third common pattern where the generic function is
199546c816aSDonát Nagy // called with `&Variable` and `sizeof(Variable)`. Right now these are
200546c816aSDonát Nagy // reported by the `sizeof(pointer)` checks, but this causes some false
201546c816aSDonát Nagy // positives, so it would be good to create an exception for them.
202546c816aSDonát Nagy some_generic_function(&IntPP, sizeof(IntP));
203*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: suspicious usage of 'sizeof()' on an expression of pointer type
204546c816aSDonát Nagy some_generic_function(&ClassPP, sizeof(ClassP));
205*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression of pointer type
206546c816aSDonát Nagy }
207546c816aSDonát Nagy
ValidExpressions()208546c816aSDonát Nagy int ValidExpressions() {
209546c816aSDonát Nagy int A[] = {1, 2, 3, 4};
210546c816aSDonát Nagy static const char str[] = "hello";
211546c816aSDonát Nagy static const char* ptr[] { "aaa", "bbb", "ccc" };
212546c816aSDonát Nagy typedef C *CA10[10];
213546c816aSDonát Nagy C *PtrArray[10];
214546c816aSDonát Nagy CA10 PtrArray1;
215546c816aSDonát Nagy
216546c816aSDonát Nagy int sum = 0;
217546c816aSDonát Nagy if (sizeof(A) < 10)
218546c816aSDonát Nagy sum += sizeof(A);
219546c816aSDonát Nagy sum += sizeof(int);
220546c816aSDonát Nagy sum += sizeof(AsStruct());
221546c816aSDonát Nagy sum += sizeof(M{}.AsStruct());
222546c816aSDonát Nagy sum += sizeof(A[sizeof(A) / sizeof(int)]);
223546c816aSDonát Nagy // Here the outer sizeof is reported, but the inner ones are accepted:
224546c816aSDonát Nagy sum += sizeof(&A[sizeof(A) / sizeof(int)]);
225*fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type
226546c816aSDonát Nagy sum += sizeof(sizeof(0)); // Special case: sizeof size_t.
227546c816aSDonát Nagy sum += sizeof(void*);
228546c816aSDonát Nagy sum += sizeof(void const *);
229546c816aSDonát Nagy sum += sizeof(void const *) / 4;
230546c816aSDonát Nagy sum += sizeof(str);
231546c816aSDonát Nagy sum += sizeof(str) / sizeof(char);
232546c816aSDonát Nagy sum += sizeof(str) / sizeof(str[0]);
233546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(ptr[0]);
234546c816aSDonát Nagy sum += sizeof(ptr) / sizeof(*(ptr));
235546c816aSDonát Nagy sum += sizeof(PtrArray) / sizeof(PtrArray[0]);
236546c816aSDonát Nagy // Canonical type of PtrArray1 is same as PtrArray.
237546c816aSDonát Nagy sum = sizeof(PtrArray) / sizeof(PtrArray1[0]);
238546c816aSDonát Nagy // There is no warning for 'sizeof(T*)/sizeof(Q)' case.
239546c816aSDonát Nagy sum += sizeof(PtrArray) / sizeof(A[0]);
240546c816aSDonát Nagy return sum;
241546c816aSDonát Nagy }
242