1 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s 2 // 3 extern "C" void *memset(void *, int, unsigned); 4 extern "C" void *memmove(void *s1, const void *s2, unsigned n); 5 extern "C" void *memcpy(void *s1, const void *s2, unsigned n); 6 7 struct S {int a, b, c, d;}; 8 typedef S* PS; 9 10 struct Foo {}; 11 typedef const Foo& CFooRef; 12 typedef const Foo CFoo; 13 typedef volatile Foo VFoo; 14 typedef const volatile Foo CVFoo; 15 16 typedef double Mat[4][4]; 17 18 template <class Dest, class Source> 19 inline Dest bit_cast(const Source& source) { 20 Dest dest; 21 memcpy(&dest, &source, sizeof(dest)); 22 return dest; 23 } 24 25 // http://www.lysator.liu.se/c/c-faq/c-2.html#2-6 26 void f(char fake_array[8], Mat m, const Foo& const_foo) { 27 S s; 28 S* ps = &s; 29 PS ps2 = &s; 30 char arr[5]; 31 char* parr[5]; 32 Foo foo; 33 34 /* Should warn */ 35 memset(&s, 0, sizeof(&s)); // \ 36 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}} 37 memset(ps, 0, sizeof(ps)); // \ 38 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}} 39 memset(ps2, 0, sizeof(ps2)); // \ 40 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}} 41 memset(ps2, 0, sizeof(typeof(ps2))); // \ 42 // expected-warning {{the argument to sizeof is pointer type 'typeof (ps2)' (aka 'S *'), expected 'S' to match first argument to 'memset'}} 43 memset(ps2, 0, sizeof(PS)); // \ 44 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}} 45 memset(fake_array, 0, sizeof(fake_array)); // \ 46 // expected-warning {{the argument to sizeof is pointer type 'char *', expected 'char' to match first argument to 'memset'}} 47 48 memcpy(&s, 0, sizeof(&s)); // \ 49 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memcpy'}} 50 memcpy(0, &s, sizeof(&s)); // \ 51 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match second argument to 'memcpy'}} 52 53 /* Shouldn't warn */ 54 memset((void*)&s, 0, sizeof(&s)); 55 memset(&s, 0, sizeof(s)); 56 memset(&s, 0, sizeof(S)); 57 memset(&s, 0, sizeof(const S)); 58 memset(&s, 0, sizeof(volatile S)); 59 memset(&s, 0, sizeof(volatile const S)); 60 memset(&foo, 0, sizeof(CFoo)); 61 memset(&foo, 0, sizeof(VFoo)); 62 memset(&foo, 0, sizeof(CVFoo)); 63 memset(ps, 0, sizeof(*ps)); 64 memset(ps2, 0, sizeof(*ps2)); 65 memset(ps2, 0, sizeof(typeof(*ps2))); 66 memset(arr, 0, sizeof(arr)); 67 memset(parr, 0, sizeof(parr)); 68 69 memcpy(&foo, &const_foo, sizeof(Foo)); 70 memcpy((void*)&s, 0, sizeof(&s)); 71 memcpy(0, (void*)&s, sizeof(&s)); 72 73 CFooRef cfoo = foo; 74 memcpy(&foo, &cfoo, sizeof(Foo)); 75 76 memcpy(0, &arr, sizeof(arr)); 77 typedef char Buff[8]; 78 memcpy(0, &arr, sizeof(Buff)); 79 80 unsigned char* puc; 81 bit_cast<char*>(puc); 82 83 float* pf; 84 bit_cast<int*>(pf); 85 86 int iarr[14]; 87 memset(&iarr[0], 0, sizeof iarr); 88 89 int* iparr[14]; 90 memset(&iparr[0], 0, sizeof iparr); 91 92 memset(m, 0, sizeof(Mat)); 93 94 // Copy to raw buffer shouldn't warn either 95 memcpy(&foo, &arr, sizeof(Foo)); 96 memcpy(&arr, &foo, sizeof(Foo)); 97 } 98