155080a78c81733021b45fc3a47541619e4470883Nico Weber// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s 2e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber// 3e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberextern "C" void *memset(void *, int, unsigned); 4e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberextern "C" void *memmove(void *s1, const void *s2, unsigned n); 5e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberextern "C" void *memcpy(void *s1, const void *s2, unsigned n); 6cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gayextern "C" void *memcmp(void *s1, const void *s2, unsigned n); 7e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 8e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberstruct S {int a, b, c, d;}; 9e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef S* PS; 10e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 11e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberstruct Foo {}; 12e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef const Foo& CFooRef; 13e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef const Foo CFoo; 14e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef volatile Foo VFoo; 15e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef const volatile Foo CVFoo; 16e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 17e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertypedef double Mat[4][4]; 18e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 19e4a1c64700304459ac436fe29cb498f2da3b6194Nico Webertemplate <class Dest, class Source> 20e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weberinline Dest bit_cast(const Source& source) { 21e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber Dest dest; 22e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&dest, &source, sizeof(dest)); 23e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber return dest; 24e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber} 25e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 26e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber// http://www.lysator.liu.se/c/c-faq/c-2.html#2-6 27c7b993b4dfc14ca2389087f21467259de8af7e91Chandler Carruthvoid f(Mat m, const Foo& const_foo, char *buffer) { 28e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber S s; 29e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber S* ps = &s; 30e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber PS ps2 = &s; 31e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber char arr[5]; 32e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber char* parr[5]; 33e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber Foo foo; 34000d428347f352979e0f6dffcf0a64e73af0a2b5Chandler Carruth char* heap_buffer = new char[42]; 35e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 36e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber /* Should warn */ 37e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(&s)); // \ 3890c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}} 39e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps, 0, sizeof(ps)); // \ 4090c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}} 41e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps2, 0, sizeof(ps2)); // \ 4290c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}} 43e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps2, 0, sizeof(typeof(ps2))); // \ 44000d428347f352979e0f6dffcf0a64e73af0a2b5Chandler Carruth // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} 45e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps2, 0, sizeof(PS)); // \ 46000d428347f352979e0f6dffcf0a64e73af0a2b5Chandler Carruth // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}} 47000d428347f352979e0f6dffcf0a64e73af0a2b5Chandler Carruth memset(heap_buffer, 0, sizeof(heap_buffer)); // \ 4890c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memset' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}} 49e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 50e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&s, 0, sizeof(&s)); // \ 5190c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}} 52e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(0, &s, sizeof(&s)); // \ 5390c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}} 54e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 55cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay memmove(ps, 0, sizeof(ps)); // \ 5690c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memmove' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}} 57cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay memcmp(ps, 0, sizeof(ps)); // \ 5890c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'memcmp' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}} 59cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay 60e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber /* Shouldn't warn */ 61e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset((void*)&s, 0, sizeof(&s)); 62e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(s)); 63e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(S)); 64e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(const S)); 65e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(volatile S)); 66e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&s, 0, sizeof(volatile const S)); 67e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&foo, 0, sizeof(CFoo)); 68e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&foo, 0, sizeof(VFoo)); 69e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&foo, 0, sizeof(CVFoo)); 70e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps, 0, sizeof(*ps)); 71e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps2, 0, sizeof(*ps2)); 72e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(ps2, 0, sizeof(typeof(*ps2))); 73e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(arr, 0, sizeof(arr)); 74e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(parr, 0, sizeof(parr)); 75e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 76e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&foo, &const_foo, sizeof(Foo)); 77e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy((void*)&s, 0, sizeof(&s)); 78e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(0, (void*)&s, sizeof(&s)); 79c7b993b4dfc14ca2389087f21467259de8af7e91Chandler Carruth char *cptr; 80c7b993b4dfc14ca2389087f21467259de8af7e91Chandler Carruth memcpy(&cptr, buffer, sizeof(cptr)); 81c7b993b4dfc14ca2389087f21467259de8af7e91Chandler Carruth memcpy((char*)&cptr, buffer, sizeof(cptr)); 82e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 83e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber CFooRef cfoo = foo; 84e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&foo, &cfoo, sizeof(Foo)); 85e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 86e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(0, &arr, sizeof(arr)); 87e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber typedef char Buff[8]; 88e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(0, &arr, sizeof(Buff)); 89e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 90e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber unsigned char* puc; 91e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber bit_cast<char*>(puc); 92e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 93e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber float* pf; 94e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber bit_cast<int*>(pf); 95e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 96e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber int iarr[14]; 97e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&iarr[0], 0, sizeof iarr); 98e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 99e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber int* iparr[14]; 100e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(&iparr[0], 0, sizeof iparr); 101e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 102e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memset(m, 0, sizeof(Mat)); 103e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber 104e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber // Copy to raw buffer shouldn't warn either 105e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&foo, &arr, sizeof(Foo)); 106e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber memcpy(&arr, &foo, sizeof(Foo)); 107dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne 108dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne // Shouldn't warn, and shouldn't crash either. 109dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne memset(({ 110dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne if (0) {} 111dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne while (0) {} 112dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne for (;;) {} 113dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne &s; 114dca1761c9b91d0a730ac6368425dc978e8481392Peter Collingbourne }), 0, sizeof(s)); 115e4a1c64700304459ac436fe29cb498f2da3b6194Nico Weber} 116cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay 117cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gaynamespace ns { 118cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gayvoid memset(void* s, char c, int n); 119cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gayvoid f(int* i) { 120cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay memset(i, 0, sizeof(i)); 121cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay} 122cc2f30c4ed7770b6005bd55b529a55c1fcc250fcMatt Beaumont-Gay} 123cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber 124cda57822327499aeb6fe606f9cf5903cffca3444Nico Weberextern "C" int strncmp(const char *s1, const char *s2, unsigned n); 125cda57822327499aeb6fe606f9cf5903cffca3444Nico Weberextern "C" int strncasecmp(const char *s1, const char *s2, unsigned n); 126cda57822327499aeb6fe606f9cf5903cffca3444Nico Weberextern "C" char *strncpy(char *det, const char *src, unsigned n); 127cda57822327499aeb6fe606f9cf5903cffca3444Nico Weberextern "C" char *strncat(char *dst, const char *src, unsigned n); 128cda57822327499aeb6fe606f9cf5903cffca3444Nico Weberextern "C" char *strndup(const char *src, unsigned n); 129cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber 130cda57822327499aeb6fe606f9cf5903cffca3444Nico Webervoid strcpy_and_friends() { 131cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber const char* FOO = "<- should be an array instead"; 132cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber const char* BAR = "<- this, too"; 133cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber 134cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber strncmp(FOO, BAR, sizeof(FOO)); // \ 13590c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'strncmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}} 136cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber strncasecmp(FOO, BAR, sizeof(FOO)); // \ 13790c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'strncasecmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}} 138cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber 139cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber char buff[80]; 140cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber 141cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber strncpy(buff, BAR, sizeof(BAR)); // \ 14290c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'strncpy' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}} 143cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber strndup(FOO, sizeof(FOO)); // \ 14490c78328e70cb376754edf87708505a84c044271Anna Zaks // expected-warning {{'strndup' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}} 145cda57822327499aeb6fe606f9cf5903cffca3444Nico Weber} 146