242 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true, bugprone-sizeof-expression.WarnOnSizeOfPointer: 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 89 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 Test1(const char* ptr) {33 int sum = 0;34 sum += sizeof(LEN);35 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'36 sum += sizeof(LEN + 1);37 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'38 sum += sizeof(sum, LEN);39 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)'40 sum += sizeof(AsBool());41 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type42 sum += sizeof(AsInt());43 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type44 sum += sizeof(AsEnum());45 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type46 sum += sizeof(AsEnumClass());47 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type48 sum += sizeof(M{}.AsInt());49 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type50 sum += sizeof(M{}.AsEnum());51 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type52 sum += sizeof(sizeof(X));53 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'54 sum += sizeof(LEN + sizeof(X));55 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'56 sum += sizeof(LEN + LEN + sizeof(X));57 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'58 sum += sizeof(LEN + (LEN + sizeof(X)));59 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'60 sum += sizeof(LEN + -sizeof(X));61 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'62 sum += sizeof(LEN + - + -sizeof(X));63 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'64 sum += sizeof(char) / sizeof(char);65 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type66 sum += sizeof(A) / sizeof(S);67 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator68 sum += sizeof(char) / sizeof(int);69 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator70 sum += sizeof(char) / sizeof(A);71 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator72 sum += sizeof(B[0]) / sizeof(A);73 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator74 sum += sizeof(ptr) / sizeof(char);75 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type76 sum += sizeof(ptr) / sizeof(ptr[0]);77 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type78 sum += sizeof(ptr) / sizeof(char*);79 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type80 sum += sizeof(ptr) / sizeof(void*);81 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type82 sum += sizeof(ptr) / sizeof(const void volatile*);83 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type84 sum += sizeof(ptr) / sizeof(char);85 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type86 sum += sizeof(int) * sizeof(char);87 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication88 sum += sizeof(ptr) * sizeof(ptr[0]);89 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type90 // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication91 sum += sizeof(int) * (2 * sizeof(char));92 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication93 sum += (2 * sizeof(char)) * sizeof(int);94 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication95 if (sizeof(A) < 0x100000) sum += 42;96 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant97 if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;98 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant99 return sum;100}101 102int Test5() {103 typedef int Array10[10];104 typedef C ArrayC[10];105 106 struct MyStruct {107 Array10 arr;108 Array10* ptr;109 };110 typedef const MyStruct TMyStruct;111 typedef const MyStruct *PMyStruct;112 typedef TMyStruct *PMyStruct2;113 114 static TMyStruct kGlocalMyStruct = {};115 static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;116 117 MyStruct S;118 PMyStruct PS;119 PMyStruct2 PS2;120 Array10 A10;121 C *PtrArray[10];122 C *PC;123 124 char *PChar;125 int *PInt, **PPInt;126 MyStruct **PPMyStruct;127 128 int sum = 0;129 sum += sizeof(&S.arr);130 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type131 sum += sizeof(&kGlocalMyStruct.arr);132 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type133 sum += sizeof(&kGlocalMyStructPtr->arr);134 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type135 sum += sizeof(S.arr + 0);136 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type137 sum += sizeof(+ S.arr);138 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type139 sum += sizeof((int*)S.arr);140 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type141 142 sum += sizeof(S.ptr);143 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type144 sum += sizeof(kGlocalMyStruct.ptr);145 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type146 sum += sizeof(kGlocalMyStructPtr->ptr);147 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type148 149 sum += sizeof(&kGlocalMyStruct);150 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type151 sum += sizeof(&S);152 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type153 sum += sizeof(MyStruct*);154 sum += sizeof(PMyStruct);155 sum += sizeof(PS);156 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type157 sum += sizeof(PS2);158 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type159 sum += sizeof(&A10);160 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type161 sum += sizeof(PtrArray) / sizeof(PtrArray[1]);162 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression of pointer type163 sum += sizeof(A10) / sizeof(PtrArray[0]);164 sum += sizeof(PC) / sizeof(PtrArray[0]);165 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type166 // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type167 sum += sizeof(ArrayC) / sizeof(PtrArray[0]);168 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator169 170 sum += sizeof(PChar);171 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type172 sum += sizeof(PInt);173 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type174 sum += sizeof(PPInt);175 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type176 sum += sizeof(PPMyStruct);177 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type178 179 return sum;180}181 182void some_generic_function(const void *arg, int argsize);183int *IntP, **IntPP;184C *ClassP, **ClassPP;185 186void GenericFunctionTest() {187 // The `sizeof(pointer)` checks ignore situations where the pointer is188 // produced by dereferencing a pointer-to-pointer, because this is unlikely189 // to be an accident and can appear in legitimate code that tries to call190 // a generic function which emulates dynamic typing within C.191 some_generic_function(IntPP, sizeof(*IntPP));192 some_generic_function(ClassPP, sizeof(*ClassPP));193 // Using `...[0]` instead of the dereference operator is another common194 // variant, which is also widespread in the idiomatic array-size calculation:195 // `sizeof(array) / sizeof(array[0])`.196 some_generic_function(IntPP, sizeof(IntPP[0]));197 some_generic_function(ClassPP, sizeof(ClassPP[0]));198 // FIXME: There is a third common pattern where the generic function is199 // called with `&Variable` and `sizeof(Variable)`. Right now these are200 // reported by the `sizeof(pointer)` checks, but this causes some false201 // positives, so it would be good to create an exception for them.202 some_generic_function(&IntPP, sizeof(IntP));203 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: suspicious usage of 'sizeof()' on an expression of pointer type204 some_generic_function(&ClassPP, sizeof(ClassP));205 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression of pointer type206}207 208int ValidExpressions() {209 int A[] = {1, 2, 3, 4};210 static const char str[] = "hello";211 static const char* ptr[] { "aaa", "bbb", "ccc" };212 typedef C *CA10[10];213 C *PtrArray[10];214 CA10 PtrArray1;215 216 int sum = 0;217 if (sizeof(A) < 10)218 sum += sizeof(A);219 sum += sizeof(int);220 sum += sizeof(AsStruct());221 sum += sizeof(M{}.AsStruct());222 sum += sizeof(A[sizeof(A) / sizeof(int)]);223 // Here the outer sizeof is reported, but the inner ones are accepted:224 sum += sizeof(&A[sizeof(A) / sizeof(int)]);225 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type226 sum += sizeof(sizeof(0)); // Special case: sizeof size_t.227 sum += sizeof(void*);228 sum += sizeof(void const *);229 sum += sizeof(void const *) / 4;230 sum += sizeof(str);231 sum += sizeof(str) / sizeof(char);232 sum += sizeof(str) / sizeof(str[0]);233 sum += sizeof(ptr) / sizeof(ptr[0]);234 sum += sizeof(ptr) / sizeof(*(ptr));235 sum += sizeof(PtrArray) / sizeof(PtrArray[0]);236 // Canonical type of PtrArray1 is same as PtrArray.237 sum = sizeof(PtrArray) / sizeof(PtrArray1[0]);238 // There is no warning for 'sizeof(T*)/sizeof(Q)' case.239 sum += sizeof(PtrArray) / sizeof(A[0]);240 return sum;241}242