1e8a3ddafSNathan James // RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true}}" -- 289a1d03eSRichard 389a1d03eSRichard class C { 489a1d03eSRichard int size() { return sizeof(this); } 589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)' 689a1d03eSRichard }; 789a1d03eSRichard 889a1d03eSRichard #define LEN 8 989a1d03eSRichard 1089a1d03eSRichard int X; 1189a1d03eSRichard extern int A[10]; 1289a1d03eSRichard extern short B[10]; 1389a1d03eSRichard 1489a1d03eSRichard #pragma pack(1) 1589a1d03eSRichard struct S { char a, b, c; }; 1689a1d03eSRichard 1789a1d03eSRichard enum E { E_VALUE = 0 }; 1889a1d03eSRichard enum class EC { VALUE = 0 }; 1989a1d03eSRichard 2089a1d03eSRichard bool AsBool() { return false; } 2189a1d03eSRichard int AsInt() { return 0; } 2289a1d03eSRichard E AsEnum() { return E_VALUE; } 2389a1d03eSRichard EC AsEnumClass() { return EC::VALUE; } 2489a1d03eSRichard S AsStruct() { return {}; } 2589a1d03eSRichard 2689a1d03eSRichard struct M { 2789a1d03eSRichard int AsInt() { return 0; } 2889a1d03eSRichard E AsEnum() { return E_VALUE; } 2989a1d03eSRichard S AsStruct() { return {}; } 3089a1d03eSRichard }; 3189a1d03eSRichard 3289a1d03eSRichard int ReturnOverload(int) { return {}; } 3389a1d03eSRichard S ReturnOverload(S) { return {}; } 3489a1d03eSRichard 3589a1d03eSRichard template <class T> 3689a1d03eSRichard T ReturnTemplate(T) { return {}; } 3789a1d03eSRichard 3889a1d03eSRichard template <class T> 3989a1d03eSRichard bool TestTrait1() { 4089a1d03eSRichard return sizeof(ReturnOverload(T{})) == sizeof(A); 4189a1d03eSRichard } 4289a1d03eSRichard 4389a1d03eSRichard template <class T> 4489a1d03eSRichard bool TestTrait2() { 4589a1d03eSRichard return sizeof(ReturnTemplate(T{})) == sizeof(A); 4689a1d03eSRichard } 4789a1d03eSRichard 4889a1d03eSRichard template <class T> 4989a1d03eSRichard bool TestTrait3() { 5089a1d03eSRichard return sizeof(ReturnOverload(0)) == sizeof(T{}); 51fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 5289a1d03eSRichard } 5389a1d03eSRichard 5489a1d03eSRichard template <class T> 5589a1d03eSRichard bool TestTrait4() { 5689a1d03eSRichard return sizeof(ReturnTemplate(0)) == sizeof(T{}); 57fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 5889a1d03eSRichard } 5989a1d03eSRichard 6089a1d03eSRichard bool TestTemplates() { 6189a1d03eSRichard bool b = true; 6289a1d03eSRichard b &= TestTrait1<int>(); 6389a1d03eSRichard b &= TestTrait1<S>(); 6489a1d03eSRichard b &= TestTrait2<int>(); 6589a1d03eSRichard b &= TestTrait2<S>(); 6689a1d03eSRichard b &= TestTrait3<int>(); 6789a1d03eSRichard b &= TestTrait3<S>(); 6889a1d03eSRichard b &= TestTrait4<int>(); 6989a1d03eSRichard b &= TestTrait4<S>(); 7089a1d03eSRichard return b; 7189a1d03eSRichard } 7289a1d03eSRichard 7389a1d03eSRichard int Test1(const char* ptr) { 7489a1d03eSRichard int sum = 0; 7589a1d03eSRichard sum += sizeof(LEN); 7689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' 7789a1d03eSRichard sum += sizeof(LEN + 1); 7889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)' 7989a1d03eSRichard sum += sizeof(sum, LEN); 800e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)' 8189a1d03eSRichard sum += sizeof(AsBool()); 82fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 8389a1d03eSRichard sum += sizeof(AsInt()); 84fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 8589a1d03eSRichard sum += sizeof(AsEnum()); 86fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 8789a1d03eSRichard sum += sizeof(AsEnumClass()); 88fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 8989a1d03eSRichard sum += sizeof(M{}.AsInt()); 90fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 9189a1d03eSRichard sum += sizeof(M{}.AsEnum()); 92fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type 9389a1d03eSRichard sum += sizeof(sizeof(X)); 9489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 9589a1d03eSRichard sum += sizeof(LEN + sizeof(X)); 9689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 9789a1d03eSRichard sum += sizeof(LEN + LEN + sizeof(X)); 9889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 9989a1d03eSRichard sum += sizeof(LEN + (LEN + sizeof(X))); 10089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 10189a1d03eSRichard sum += sizeof(LEN + -sizeof(X)); 10289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 10389a1d03eSRichard sum += sizeof(LEN + - + -sizeof(X)); 10489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))' 10589a1d03eSRichard sum += sizeof(char) / sizeof(char); 106fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 10789a1d03eSRichard sum += sizeof(A) / sizeof(S); 1080e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 10989a1d03eSRichard sum += sizeof(char) / sizeof(int); 1100e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 11189a1d03eSRichard sum += sizeof(char) / sizeof(A); 1120e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 11389a1d03eSRichard sum += sizeof(B[0]) / sizeof(A); 1140e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 11589a1d03eSRichard sum += sizeof(ptr) / sizeof(char); 116fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type 11789a1d03eSRichard sum += sizeof(ptr) / sizeof(ptr[0]); 118fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type 11989a1d03eSRichard sum += sizeof(ptr) / sizeof(char*); 120fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types 12189a1d03eSRichard sum += sizeof(ptr) / sizeof(void*); 122fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types 12389a1d03eSRichard sum += sizeof(ptr) / sizeof(const void volatile*); 124fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types 12589a1d03eSRichard sum += sizeof(ptr) / sizeof(char); 126fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type 12789a1d03eSRichard sum += sizeof(int) * sizeof(char); 1280e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication 12989a1d03eSRichard sum += sizeof(ptr) * sizeof(ptr[0]); 1300e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication 13189a1d03eSRichard sum += sizeof(int) * (2 * sizeof(char)); 1320e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication 13389a1d03eSRichard sum += (2 * sizeof(char)) * sizeof(int); 1340e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication 13589a1d03eSRichard if (sizeof(A) < 0x100000) sum += 42; 1360e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant 13789a1d03eSRichard if (sizeof(A) <= 0xFFFFFFFEU) sum += 42; 1380e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant 13989a1d03eSRichard return sum; 14089a1d03eSRichard } 14189a1d03eSRichard 14289a1d03eSRichard typedef char MyChar; 14389a1d03eSRichard typedef const MyChar MyConstChar; 14489a1d03eSRichard 14589a1d03eSRichard int CE0 = sizeof sizeof(char); 14689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' 14789a1d03eSRichard int CE1 = sizeof +sizeof(char); 14889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' 14989a1d03eSRichard int CE2 = sizeof sizeof(const char*); 15089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' 15189a1d03eSRichard int CE3 = sizeof sizeof(const volatile char* const*); 15289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' 15389a1d03eSRichard int CE4 = sizeof sizeof(MyConstChar); 15489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))' 15589a1d03eSRichard 15689a1d03eSRichard int Test2(MyConstChar* A) { 15789a1d03eSRichard int sum = 0; 15889a1d03eSRichard sum += sizeof(MyConstChar) / sizeof(char); 159fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 16089a1d03eSRichard sum += sizeof(MyConstChar) / sizeof(MyChar); 161fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 16289a1d03eSRichard sum += sizeof(A[0]) / sizeof(char); 163fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 16489a1d03eSRichard return sum; 16589a1d03eSRichard } 16689a1d03eSRichard 16789a1d03eSRichard template <int T> 16889a1d03eSRichard int Foo() { int A[T]; return sizeof(T); } 16989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)' 17089a1d03eSRichard template <typename T> 17189a1d03eSRichard int Bar() { T A[5]; return sizeof(A[0]) / sizeof(T); } 172fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 17389a1d03eSRichard int Test3() { return Foo<42>() + Bar<char>(); } 17489a1d03eSRichard 17589a1d03eSRichard static const char* kABC = "abc"; 17689a1d03eSRichard static const wchar_t* kDEF = L"def"; 17789a1d03eSRichard int Test4(const char A[10]) { 17889a1d03eSRichard int sum = 0; 17989a1d03eSRichard sum += sizeof(kABC); 18089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)' 18189a1d03eSRichard sum += sizeof(kDEF); 18289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)' 18389a1d03eSRichard return sum; 18489a1d03eSRichard } 18589a1d03eSRichard 18689a1d03eSRichard int Test5() { 18789a1d03eSRichard typedef int Array10[10]; 18889a1d03eSRichard typedef C ArrayC[10]; 18989a1d03eSRichard 19089a1d03eSRichard struct MyStruct { 19189a1d03eSRichard Array10 arr; 19289a1d03eSRichard Array10* ptr; 19389a1d03eSRichard }; 19489a1d03eSRichard typedef const MyStruct TMyStruct; 19589a1d03eSRichard typedef const MyStruct *PMyStruct; 19689a1d03eSRichard typedef TMyStruct *PMyStruct2; 19789a1d03eSRichard 19889a1d03eSRichard static TMyStruct kGlocalMyStruct = {}; 19989a1d03eSRichard static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct; 20089a1d03eSRichard 20189a1d03eSRichard MyStruct S; 20289a1d03eSRichard PMyStruct PS; 20389a1d03eSRichard PMyStruct2 PS2; 20489a1d03eSRichard Array10 A10; 20589a1d03eSRichard C *PtrArray[10]; 20689a1d03eSRichard C *PC; 20789a1d03eSRichard 208546c816aSDonát Nagy char *PChar; 209546c816aSDonát Nagy int *PInt, **PPInt; 210546c816aSDonát Nagy MyStruct **PPMyStruct; 211546c816aSDonát Nagy 21289a1d03eSRichard int sum = 0; 21389a1d03eSRichard sum += sizeof(&S.arr); 214fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 21589a1d03eSRichard sum += sizeof(&kGlocalMyStruct.arr); 216fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 21789a1d03eSRichard sum += sizeof(&kGlocalMyStructPtr->arr); 218fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 21989a1d03eSRichard sum += sizeof(S.arr + 0); 220fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 22189a1d03eSRichard sum += sizeof(+ S.arr); 222fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 22389a1d03eSRichard sum += sizeof((int*)S.arr); 224fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 22589a1d03eSRichard 22689a1d03eSRichard sum += sizeof(S.ptr); 227fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 22889a1d03eSRichard sum += sizeof(kGlocalMyStruct.ptr); 229fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 23089a1d03eSRichard sum += sizeof(kGlocalMyStructPtr->ptr); 231fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 23289a1d03eSRichard 23389a1d03eSRichard sum += sizeof(&kGlocalMyStruct); 234fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 23589a1d03eSRichard sum += sizeof(&S); 236fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 23789a1d03eSRichard sum += sizeof(MyStruct*); 23889a1d03eSRichard sum += sizeof(PMyStruct); 23989a1d03eSRichard sum += sizeof(PS); 240fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 24189a1d03eSRichard sum += sizeof(PS2); 242fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 24389a1d03eSRichard sum += sizeof(&A10); 244fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 24589a1d03eSRichard sum += sizeof(PtrArray) / sizeof(PtrArray[1]); 246fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression of pointer type 24789a1d03eSRichard sum += sizeof(A10) / sizeof(PtrArray[0]); 24889a1d03eSRichard sum += sizeof(PC) / sizeof(PtrArray[0]); 249fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type 250fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type 25189a1d03eSRichard sum += sizeof(ArrayC) / sizeof(PtrArray[0]); 2520e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 253546c816aSDonát Nagy 254546c816aSDonát Nagy // These pointers do not point to aggregate types, so they are not reported in this mode: 255546c816aSDonát Nagy sum += sizeof(PChar); 256546c816aSDonát Nagy sum += sizeof(PInt); 257546c816aSDonát Nagy sum += sizeof(PPInt); 258546c816aSDonát Nagy sum += sizeof(PPMyStruct); 25989a1d03eSRichard 26089a1d03eSRichard return sum; 26189a1d03eSRichard } 26289a1d03eSRichard 26389a1d03eSRichard int Test6() { 26489a1d03eSRichard int sum = 0; 26589a1d03eSRichard 26689a1d03eSRichard struct S A = AsStruct(), B = AsStruct(); 26789a1d03eSRichard struct S *P = &A, *Q = &B; 26889a1d03eSRichard sum += sizeof(struct S) == P - Q; 26989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 27089a1d03eSRichard sum += 5 * sizeof(S) != P - Q; 2710e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 27289a1d03eSRichard sum += sizeof(S) < P - Q; 27389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 27489a1d03eSRichard sum += 5 * sizeof(S) <= P - Q; 2750e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 27689a1d03eSRichard sum += 5 * sizeof(*P) >= P - Q; 2770e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 27889a1d03eSRichard sum += Q - P > 3 * sizeof(*P); 2790e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 28089a1d03eSRichard sum += sizeof(S) + (P - Q); 28189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 28289a1d03eSRichard sum += 5 * sizeof(S) - (P - Q); 2830e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 28489a1d03eSRichard sum += (P - Q) / sizeof(S); 2850e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 28689a1d03eSRichard sum += (P - Q) / sizeof(*Q); 2870e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic 28889a1d03eSRichard 28989a1d03eSRichard return sum; 29089a1d03eSRichard } 29189a1d03eSRichard 292267ad430SZoltán Porkoláb static constexpr inline int BufferSize = 1024; 293267ad430SZoltán Porkoláb 294267ad430SZoltán Porkoláb template <typename T> 295267ad430SZoltán Porkoláb T next(const T *&Read) { 296267ad430SZoltán Porkoláb T value = *Read; 297267ad430SZoltán Porkoláb Read += sizeof(T); 298267ad430SZoltán Porkoláb return value; 299267ad430SZoltán Porkoláb } 300267ad430SZoltán Porkoláb 301267ad430SZoltán Porkoláb void Test7() { 302267ad430SZoltán Porkoláb int Buffer[BufferSize]; 303267ad430SZoltán Porkoláb int *P = &Buffer[0]; 304267ad430SZoltán Porkoláb 305267ad430SZoltán Porkoláb const int *P2 = P; 306267ad430SZoltán Porkoláb int V1 = next(P2); 307267ad430SZoltán Porkoláb // CHECK-MESSAGES: :[[@LINE-10]]:8: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic; this scaled value will be scaled again by the '+=' operator 308267ad430SZoltán Porkoláb // CHECK-MESSAGES: :[[@LINE-11]]:8: note: '+=' in pointer arithmetic internally scales with 'sizeof(const int)' == {{[0-9]+}} 309267ad430SZoltán Porkoláb int V2 = next(P2); 310267ad430SZoltán Porkoláb (void)V1; 311267ad430SZoltán Porkoláb (void)V2; 312267ad430SZoltán Porkoláb 313267ad430SZoltán Porkoláb int *Q = P; 314267ad430SZoltán Porkoláb while (Q < P + sizeof(Buffer)) { 315267ad430SZoltán Porkoláb // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic; this scaled value will be scaled again by the '+' operator 316267ad430SZoltán Porkoláb // CHECK-MESSAGES: :[[@LINE-2]]:16: note: '+' in pointer arithmetic internally scales with 'sizeof(int)' == {{[0-9]+}} 317267ad430SZoltán Porkoláb *Q++ = 0; 318267ad430SZoltán Porkoláb } 319267ad430SZoltán Porkoláb } 320267ad430SZoltán Porkoláb 32189a1d03eSRichard #ifdef __SIZEOF_INT128__ 32289a1d03eSRichard template <__int128_t N> 32389a1d03eSRichard #else 32489a1d03eSRichard template <long N> // Fallback for platforms which do not define `__int128_t` 32589a1d03eSRichard #endif 32689a1d03eSRichard bool Baz() { return sizeof(A) < N; } 3270e55fef0SNathan James // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant 328267ad430SZoltán Porkoláb bool Test8() { return Baz<-1>(); } 32989a1d03eSRichard 330546c816aSDonát Nagy void some_generic_function(const void *arg, int argsize); 331546c816aSDonát Nagy int *IntP, **IntPP; 332546c816aSDonát Nagy C *ClassP, **ClassPP; 333546c816aSDonát Nagy 334546c816aSDonát Nagy void GenericFunctionTest() { 335546c816aSDonát Nagy // The `sizeof(pointer)` checks ignore situations where the pointer is 336546c816aSDonát Nagy // produced by dereferencing a pointer-to-pointer, because this is unlikely 337546c816aSDonát Nagy // to be an accident and can appear in legitimate code that tries to call 338546c816aSDonát Nagy // a generic function which emulates dynamic typing within C. 339546c816aSDonát Nagy some_generic_function(IntPP, sizeof(*IntPP)); 340546c816aSDonát Nagy some_generic_function(ClassPP, sizeof(*ClassPP)); 341546c816aSDonát Nagy // Using `...[0]` instead of the dereference operator is another common 342546c816aSDonát Nagy // variant, which is also widespread in the idiomatic array-size calculation: 343546c816aSDonát Nagy // `sizeof(array) / sizeof(array[0])`. 344546c816aSDonát Nagy some_generic_function(IntPP, sizeof(IntPP[0])); 345546c816aSDonát Nagy some_generic_function(ClassPP, sizeof(ClassPP[0])); 346546c816aSDonát Nagy // FIXME: There is a third common pattern where the generic function is 347546c816aSDonát Nagy // called with `&Variable` and `sizeof(Variable)`. Right now these are 348546c816aSDonát Nagy // reported by the `sizeof(pointer)` checks, but this causes some false 349546c816aSDonát Nagy // positives, so it would be good to create an exception for them. 350546c816aSDonát Nagy // NOTE: `sizeof(IntP)` is only reported with `WarnOnSizeOfPointer=true`. 351546c816aSDonát Nagy some_generic_function(&IntPP, sizeof(IntP)); 352546c816aSDonát Nagy some_generic_function(&ClassPP, sizeof(ClassP)); 353fdcfb277SDonát Nagy // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression of pointer type 354546c816aSDonát Nagy } 355546c816aSDonát Nagy 35689a1d03eSRichard int ValidExpressions() { 35789a1d03eSRichard int A[] = {1, 2, 3, 4}; 35889a1d03eSRichard static const char str[] = "hello"; 35989a1d03eSRichard static const char* ptr[] { "aaa", "bbb", "ccc" }; 36089a1d03eSRichard typedef C *CA10[10]; 36189a1d03eSRichard C *PtrArray[10]; 36289a1d03eSRichard CA10 PtrArray1; 36389a1d03eSRichard 36489a1d03eSRichard int sum = 0; 36589a1d03eSRichard if (sizeof(A) < 10) 36689a1d03eSRichard sum += sizeof(A); 36789a1d03eSRichard sum += sizeof(int); 36889a1d03eSRichard sum += sizeof(AsStruct()); 36989a1d03eSRichard sum += sizeof(M{}.AsStruct()); 37089a1d03eSRichard sum += sizeof(A[sizeof(A) / sizeof(int)]); 37189a1d03eSRichard sum += sizeof(&A[sizeof(A) / sizeof(int)]); 37289a1d03eSRichard sum += sizeof(sizeof(0)); // Special case: sizeof size_t. 37389a1d03eSRichard sum += sizeof(void*); 37489a1d03eSRichard sum += sizeof(void const *); 37589a1d03eSRichard sum += sizeof(void const *) / 4; 37689a1d03eSRichard sum += sizeof(str); 37789a1d03eSRichard sum += sizeof(str) / sizeof(char); 37889a1d03eSRichard sum += sizeof(str) / sizeof(str[0]); 37989a1d03eSRichard sum += sizeof(ptr) / sizeof(ptr[0]); 38089a1d03eSRichard sum += sizeof(ptr) / sizeof(*(ptr)); 38189a1d03eSRichard sum += sizeof(PtrArray) / sizeof(PtrArray[0]); 38289a1d03eSRichard // Canonical type of PtrArray1 is same as PtrArray. 38389a1d03eSRichard sum = sizeof(PtrArray) / sizeof(PtrArray1[0]); 38489a1d03eSRichard // There is no warning for 'sizeof(T*)/sizeof(Q)' case. 38589a1d03eSRichard sum += sizeof(PtrArray) / sizeof(A[0]); 38689a1d03eSRichard return sum; 38789a1d03eSRichard } 388*e855feacSCongcong Cai 389*e855feacSCongcong Cai namespace gh115175 { 390*e855feacSCongcong Cai template<class T> 391*e855feacSCongcong Cai int ValidateTemplateTypeExpressions(T t) { 392*e855feacSCongcong Cai return sizeof(t.val) / sizeof(t.val[0]); 393*e855feacSCongcong Cai } 394*e855feacSCongcong Cai } // namespace gh115175 395