brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.0 KiB · e47f8b0 Raw
467 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t \2// RUN:   -- -config="{CheckOptions: {bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression: true}}" \3// RUN:   -- -fno-delayed-template-parsing4 5class C {6  int size() { return sizeof(this); }7  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)'8};9 10#define LEN 811 12int X;13extern int A[10];14extern short B[10];15 16#pragma pack(1)17struct  S { char a, b, c; };18 19enum E { E_VALUE = 0 };20enum class EC { VALUE = 0 };21 22bool AsBool() { return false; }23int AsInt() { return 0; }24E AsEnum() { return E_VALUE; }25EC AsEnumClass() { return EC::VALUE; }26S AsStruct() { return {}; }27 28struct M {29  int AsInt() { return 0; }30  E AsEnum() { return E_VALUE; }31  S AsStruct() { return {}; }32};33 34int ReturnOverload(int) { return {}; }35S ReturnOverload(S) { return {}; }36 37template <class T>38T ReturnTemplate(T) { return {}; }39 40template <class T>41bool TestTrait1() {42  return sizeof(ReturnOverload(T{})) == sizeof(A);43}44 45template <class T>46bool TestTrait2() {47  return sizeof(ReturnTemplate(T{})) == sizeof(A);48}49 50template <class T>51bool TestTrait3() {52  return sizeof(ReturnOverload(0)) == sizeof(T{});53  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type54}55 56template <class T>57bool TestTrait4() {58  return sizeof(ReturnTemplate(0)) == sizeof(T{});59  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type60}61 62bool TestTemplates() {63  bool b = true;64  b &= TestTrait1<int>();65  b &= TestTrait1<S>();66  b &= TestTrait2<int>();67  b &= TestTrait2<S>();68  b &= TestTrait3<int>();69  b &= TestTrait3<S>();70  b &= TestTrait4<int>();71  b &= TestTrait4<S>();72  return b;73}74 75int Test1(const char* ptr) {76  int sum = 0;77  sum += sizeof(LEN);78  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'79  sum += sizeof(LEN + 1);80  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'81  sum += sizeof(sum, LEN);82  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(..., ...)'83  sum += sizeof(AsBool());84  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type85  sum += sizeof(AsInt());86  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type87  sum += sizeof(AsEnum());88  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type89  sum += sizeof(AsEnumClass());90  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type91  sum += sizeof(M{}.AsInt());92  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type93  sum += sizeof(M{}.AsEnum());94  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of integer type95  sum += sizeof(sizeof(X));96  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'97  sum += sizeof(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 + (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(LEN + - + -sizeof(X));106  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'107  sum += sizeof(char) / sizeof(char);108  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type109  sum += sizeof(A) / sizeof(S);110  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator111  sum += sizeof(char) / sizeof(int);112  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator113  sum += sizeof(char) / sizeof(A);114  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator115  sum += sizeof(B[0]) / sizeof(A);116  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator117  sum += sizeof(ptr) / sizeof(char);118  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type119  sum += sizeof(ptr) / sizeof(ptr[0]);120  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type121  sum += sizeof(ptr) / sizeof(char*);122  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types123  sum += sizeof(ptr) / sizeof(void*);124  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types125  sum += sizeof(ptr) / sizeof(const void volatile*);126  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have pointer types127  sum += sizeof(ptr) / sizeof(char);128  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer is divided by size of pointed type129  sum += sizeof(int) * sizeof(char);130  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication131  sum += sizeof(ptr) * sizeof(ptr[0]);132  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication133  sum += sizeof(int) * (2 * sizeof(char));134  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious 'sizeof' by 'sizeof' multiplication135  sum += (2 * sizeof(char)) * sizeof(int);136  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious 'sizeof' by 'sizeof' multiplication137  if (sizeof(A) < 0x100000) sum += 42;138  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant139  if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;140  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: suspicious comparison of 'sizeof(expr)' to a constant141  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(...)/sizeof(...)'; both expressions have the same type162  sum += sizeof(MyConstChar) / sizeof(MyChar);163  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type164  sum += sizeof(A[0]) / sizeof(char);165  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type166  return sum;167}168 169struct A {170   int array[10];171};172 173struct B {174  struct A a;175};176 177void loop_access_elements(int num, struct B b) {178  struct A arr[10];179  char buf[20];180 181  // CHECK-MESSAGES: :[[@LINE+1]]:22: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]182  for(int i = 0; i < sizeof(arr); i++) {183    struct A a = arr[i];184  }185 186  // Loop warning should not trigger here, even though this code is incorrect187  // CHECK-MESSAGES: :[[@LINE+2]]:22: warning: suspicious usage of 'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression]188  // CHECK-MESSAGES: :[[@LINE+1]]:32: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator [bugprone-sizeof-expression] 189  for(int i = 0; i < sizeof(10)/sizeof(A); i++) {190    struct A a = arr[i];191  }192    193  // Should not warn here194  for(int i = 0; i < sizeof(arr)/sizeof(A); i++) {}195 196  // Should not warn here197  for (int i = 0; i < 10; i++) {198    if (sizeof(arr) != 0) {199 200    }201  }202 203  for (int i = 0; i < 10; i++) {204    // CHECK-MESSAGES: :[[@LINE+1]]:25: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]205    for (int j = 0; j < sizeof(arr); j++) {206    }207  }208 209  // CHECK-MESSAGES: :[[@LINE+1]]:22: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]210  for(int j = 0; j < sizeof(b.a.array); j++) {}211  212  // Should not warn here213  for(int i = 0; i < sizeof(buf); i++) {} 214 215  // Should not warn here216  for(int i = 0; i < (sizeof(arr) << 3); i++) {}217  218  int i = 0;219  // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]220  while(i <= sizeof(arr)) {i++;}221   222  i = 0;223  do {224    i++;225  // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression] 226  } while(i <= sizeof(arr));227 228  // CHECK-MESSAGES: :[[@LINE+1]]:29: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]229  for(int i = 0, j = 0; i < sizeof(arr) && j < sizeof(buf); i++, j++) {}230}231 232template <typename T>233void templated_array() {234  T arr[10];235  // CHECK-MESSAGES: :[[@LINE+1]]:23: warning: suspicious usage of 'sizeof' in the loop [bugprone-sizeof-expression]236  for (int i = 0; i < sizeof(arr); ++i) {}237}238 239template <int T>240int Foo() { int A[T]; return sizeof(T); }241// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'242template <typename T>243int Bar() { T A[5]; return sizeof(A[0]) / sizeof(T); }244// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type245int Test3() { return Foo<42>() + Bar<char>(); }246 247static const char* kABC = "abc";248static const wchar_t* kDEF = L"def";249int Test4(const char A[10]) {250  int sum = 0;251  sum += sizeof(kABC);252  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'253  sum += sizeof(kDEF);254  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'255  return sum;256}257 258int Test5() {259  typedef int Array10[10];260  typedef C ArrayC[10];261 262  struct MyStruct {263    Array10 arr;264    Array10* ptr;265  };266  typedef const MyStruct TMyStruct;267  typedef const MyStruct *PMyStruct;268  typedef TMyStruct *PMyStruct2;269 270  static TMyStruct kGlocalMyStruct = {};271  static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;272 273  MyStruct S;274  PMyStruct PS;275  PMyStruct2 PS2;276  Array10 A10;277  C *PtrArray[10];278  C *PC;279 280  char *PChar;281  int *PInt, **PPInt;282  MyStruct **PPMyStruct;283 284  int sum = 0;285  sum += sizeof(&S.arr);286  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type287  sum += sizeof(&kGlocalMyStruct.arr);288  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type289  sum += sizeof(&kGlocalMyStructPtr->arr);290  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type291  sum += sizeof(S.arr + 0);292  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type293  sum += sizeof(+ S.arr);294  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type295  sum += sizeof((int*)S.arr);296  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type297 298  sum += sizeof(S.ptr);299  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type300  sum += sizeof(kGlocalMyStruct.ptr);301  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type302  sum += sizeof(kGlocalMyStructPtr->ptr);303  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type304 305  sum += sizeof(&kGlocalMyStruct);306  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type307  sum += sizeof(&S);308  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type309  sum += sizeof(MyStruct*);310  sum += sizeof(PMyStruct);311  sum += sizeof(PS);312  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type313  sum += sizeof(PS2);314  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type315  sum += sizeof(&A10);316  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type317  sum += sizeof(PtrArray) / sizeof(PtrArray[1]);318  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: suspicious usage of 'sizeof()' on an expression of pointer type319  sum += sizeof(A10) / sizeof(PtrArray[0]);320  sum += sizeof(PC) / sizeof(PtrArray[0]);321  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression of pointer type322  // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; both expressions have the same type323  sum += sizeof(ArrayC) / sizeof(PtrArray[0]);324  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator325 326  // These pointers do not point to aggregate types, so they are not reported in this mode:327  sum += sizeof(PChar);328  sum += sizeof(PInt);329  sum += sizeof(PPInt);330  sum += sizeof(PPMyStruct);331 332  return sum;333}334 335int Test6() {336  int sum = 0;337 338  struct S A = AsStruct(), B = AsStruct();339  struct S *P = &A, *Q = &B;340  sum += sizeof(struct S) == P - Q;341  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic342  sum += 5 * sizeof(S) != P - Q;343  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic344  sum += sizeof(S) < P - Q;345  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic346  sum += 5 * sizeof(S) <= P - Q;347  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic348  sum += 5 * sizeof(*P) >= P - Q;349  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic350  sum += Q - P > 3 * sizeof(*P);351  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic352  sum += sizeof(S) + (P - Q);353  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic354  sum += 5 * sizeof(S) - (P - Q);355  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic356  sum += (P - Q) / sizeof(S);357  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic358  sum += (P - Q) / sizeof(*Q);359  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic360 361  return sum;362}363 364static constexpr inline int BufferSize = 1024;365 366template <typename T>367T next(const T *&Read) {368  T value = *Read;369  Read += sizeof(T);370  return value;371}372 373void Test7() {374  int Buffer[BufferSize];375  int *P = &Buffer[0];376 377  const int *P2 = P;378  int V1 = next(P2);379  // CHECK-MESSAGES: :[[@LINE-10]]:8: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic; this scaled value will be scaled again by the '+=' operator380  // CHECK-MESSAGES: :[[@LINE-11]]:8: note: '+=' in pointer arithmetic internally scales with 'sizeof(const int)' == {{[0-9]+}}381  int V2 = next(P2);382  (void)V1;383  (void)V2;384 385  int *Q = P;386  while (Q < P + sizeof(Buffer)) {387    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic; this scaled value will be scaled again by the '+' operator388    // CHECK-MESSAGES: :[[@LINE-2]]:16: note: '+' in pointer arithmetic internally scales with 'sizeof(int)' == {{[0-9]+}}389    *Q++ = 0;390  }391}392 393#ifdef __SIZEOF_INT128__394template <__int128_t N>395#else396template <long N> // Fallback for platforms which do not define `__int128_t`397#endif398bool Baz() { return sizeof(A) < N; }399// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: suspicious comparison of 'sizeof(expr)' to a constant400bool Test8() { return Baz<-1>(); }401 402void some_generic_function(const void *arg, int argsize);403int *IntP, **IntPP;404C *ClassP, **ClassPP;405 406void GenericFunctionTest() {407  // The `sizeof(pointer)` checks ignore situations where the pointer is408  // produced by dereferencing a pointer-to-pointer, because this is unlikely409  // to be an accident and can appear in legitimate code that tries to call410  // a generic function which emulates dynamic typing within C.411  some_generic_function(IntPP, sizeof(*IntPP));412  some_generic_function(ClassPP, sizeof(*ClassPP));413  // Using `...[0]` instead of the dereference operator is another common414  // variant, which is also widespread in the idiomatic array-size calculation:415  // `sizeof(array) / sizeof(array[0])`.416  some_generic_function(IntPP, sizeof(IntPP[0]));417  some_generic_function(ClassPP, sizeof(ClassPP[0]));418  // FIXME: There is a third common pattern where the generic function is419  // called with `&Variable` and `sizeof(Variable)`. Right now these are420  // reported by the `sizeof(pointer)` checks, but this causes some false421  // positives, so it would be good to create an exception for them.422  // NOTE: `sizeof(IntP)` is only reported with `WarnOnSizeOfPointer=true`.423  some_generic_function(&IntPP, sizeof(IntP));424  some_generic_function(&ClassPP, sizeof(ClassP));425  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: suspicious usage of 'sizeof()' on an expression of pointer type426}427 428int ValidExpressions() {429  int A[] = {1, 2, 3, 4};430  static const char str[] = "hello";431  static const char* ptr[] { "aaa", "bbb", "ccc" };432  typedef C *CA10[10];433  C *PtrArray[10];434  CA10 PtrArray1;435 436  int sum = 0;437  if (sizeof(A) < 10)438    sum += sizeof(A);439  sum += sizeof(int);440  sum += sizeof(AsStruct());441  sum += sizeof(M{}.AsStruct());442  sum += sizeof(A[sizeof(A) / sizeof(int)]);443  sum += sizeof(&A[sizeof(A) / sizeof(int)]);444  sum += sizeof(sizeof(0));  // Special case: sizeof size_t.445  sum += sizeof(void*);446  sum += sizeof(void const *);447  sum += sizeof(void const *) / 4;448  sum += sizeof(str);449  sum += sizeof(str) / sizeof(char);450  sum += sizeof(str) / sizeof(str[0]);451  sum += sizeof(ptr) / sizeof(ptr[0]);452  sum += sizeof(ptr) / sizeof(*(ptr));453  sum += sizeof(PtrArray) / sizeof(PtrArray[0]);454  // Canonical type of PtrArray1 is same as PtrArray.455  sum = sizeof(PtrArray) / sizeof(PtrArray1[0]);456  // There is no warning for 'sizeof(T*)/sizeof(Q)' case.457  sum += sizeof(PtrArray) / sizeof(A[0]);458  return sum;459}460 461namespace gh115175 {462template<class T>463int ValidateTemplateTypeExpressions(T t) {464  return sizeof(t.val) / sizeof(t.val[0]);465}466} // namespace gh115175467