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(Mat m, const Foo& const_foo, char *buffer) { 27 S s; 28 S* ps = &s; 29 PS ps2 = &s; 30 char arr[5]; 31 char* parr[5]; 32 Foo foo; 33 char* heap_buffer = new char[42]; 34 35 /* Should warn */ 36 memset(&s, 0, sizeof(&s)); // \ 37 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} 38 memset(ps, 0, sizeof(ps)); // \ 39 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} 40 memset(ps2, 0, sizeof(ps2)); // \ 41 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} 42 memset(ps2, 0, sizeof(typeof(ps2))); // \ 43 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} 44 memset(ps2, 0, sizeof(PS)); // \ 45 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} 46 memset(heap_buffer, 0, sizeof(heap_buffer)); // \ 47 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}} 48 49 memcpy(&s, 0, sizeof(&s)); // \ 50 // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination}} 51 memcpy(0, &s, sizeof(&s)); // \ 52 // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}} 53 54 /* Shouldn't warn */ 55 memset((void*)&s, 0, sizeof(&s)); 56 memset(&s, 0, sizeof(s)); 57 memset(&s, 0, sizeof(S)); 58 memset(&s, 0, sizeof(const S)); 59 memset(&s, 0, sizeof(volatile S)); 60 memset(&s, 0, sizeof(volatile const S)); 61 memset(&foo, 0, sizeof(CFoo)); 62 memset(&foo, 0, sizeof(VFoo)); 63 memset(&foo, 0, sizeof(CVFoo)); 64 memset(ps, 0, sizeof(*ps)); 65 memset(ps2, 0, sizeof(*ps2)); 66 memset(ps2, 0, sizeof(typeof(*ps2))); 67 memset(arr, 0, sizeof(arr)); 68 memset(parr, 0, sizeof(parr)); 69 70 memcpy(&foo, &const_foo, sizeof(Foo)); 71 memcpy((void*)&s, 0, sizeof(&s)); 72 memcpy(0, (void*)&s, sizeof(&s)); 73 char *cptr; 74 memcpy(&cptr, buffer, sizeof(cptr)); 75 memcpy((char*)&cptr, buffer, sizeof(cptr)); 76 77 CFooRef cfoo = foo; 78 memcpy(&foo, &cfoo, sizeof(Foo)); 79 80 memcpy(0, &arr, sizeof(arr)); 81 typedef char Buff[8]; 82 memcpy(0, &arr, sizeof(Buff)); 83 84 unsigned char* puc; 85 bit_cast<char*>(puc); 86 87 float* pf; 88 bit_cast<int*>(pf); 89 90 int iarr[14]; 91 memset(&iarr[0], 0, sizeof iarr); 92 93 int* iparr[14]; 94 memset(&iparr[0], 0, sizeof iparr); 95 96 memset(m, 0, sizeof(Mat)); 97 98 // Copy to raw buffer shouldn't warn either 99 memcpy(&foo, &arr, sizeof(Foo)); 100 memcpy(&arr, &foo, sizeof(Foo)); 101 } 102