191 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s2//3extern "C" void *bzero(void *, unsigned);4extern "C" void *memset(void *, int, unsigned);5extern "C" void *memmove(void *s1, const void *s2, unsigned n);6extern "C" void *memcpy(void *s1, const void *s2, unsigned n);7extern "C" void *memcmp(void *s1, const void *s2, unsigned n);8 9struct S {int a, b, c, d;};10typedef S* PS;11 12struct Foo {};13typedef const Foo& CFooRef;14typedef const Foo CFoo;15typedef volatile Foo VFoo;16typedef const volatile Foo CVFoo;17 18typedef double Mat[4][4];19 20template <class Dest, class Source>21inline Dest bit_cast(const Source& source) {22 Dest dest;23 memcpy(&dest, &source, sizeof(dest));24 return dest;25}26 27// http://www.lysator.liu.se/c/c-faq/c-2.html#2-628void f(Mat m, const Foo& const_foo, char *buffer) {29 S s;30 S* ps = &s;31 PS ps2 = &s;32 char arr[5];33 char* parr[5];34 Foo foo;35 char* heap_buffer = new char[42];36 37 /* Should warn */38 memset(&s, 0, sizeof(&s)); // \39 // 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)?}}40 memset(ps, 0, sizeof(ps)); // \41 // 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)?}}42 memset(ps2, 0, sizeof(ps2)); // \43 // 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)?}}44 memset(ps2, 0, sizeof(typeof(ps2))); // \45 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}46 memset(ps2, 0, sizeof(PS)); // \47 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}48 memset(heap_buffer, 0, sizeof(heap_buffer)); // \49 // 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?}}50 51 bzero(&s, sizeof(&s)); // \52 // expected-warning {{'bzero' 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)?}}53 bzero(ps, sizeof(ps)); // \54 // expected-warning {{'bzero' 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)?}}55 bzero(ps2, sizeof(ps2)); // \56 // expected-warning {{'bzero' 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)?}}57 bzero(ps2, sizeof(typeof(ps2))); // \58 // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}59 bzero(ps2, sizeof(PS)); // \60 // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}61 bzero(heap_buffer, sizeof(heap_buffer)); // \62 // expected-warning {{'bzero' 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?}}63 64 memcpy(&s, 0, sizeof(&s)); // \65 // 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)?}}66 memcpy(0, &s, sizeof(&s)); // \67 // 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)?}}68 69 memmove(ps, 0, sizeof(ps)); // \70 // 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)?}}71 memcmp(ps, 0, sizeof(ps)); // \72 // 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)?}}73 74 /* Shouldn't warn */75 memset((void*)&s, 0, sizeof(&s));76 memset(&s, 0, sizeof(s));77 memset(&s, 0, sizeof(S));78 memset(&s, 0, sizeof(const S));79 memset(&s, 0, sizeof(volatile S));80 memset(&s, 0, sizeof(volatile const S));81 memset(&foo, 0, sizeof(CFoo));82 memset(&foo, 0, sizeof(VFoo));83 memset(&foo, 0, sizeof(CVFoo));84 memset(ps, 0, sizeof(*ps));85 memset(ps2, 0, sizeof(*ps2));86 memset(ps2, 0, sizeof(typeof(*ps2)));87 memset(arr, 0, sizeof(arr));88 memset(parr, 0, sizeof(parr));89 90 bzero((void*)&s, sizeof(&s));91 bzero(&s, sizeof(s));92 bzero(&s, sizeof(S));93 bzero(&s, sizeof(const S));94 bzero(&s, sizeof(volatile S));95 bzero(&s, sizeof(volatile const S));96 bzero(&foo, sizeof(CFoo));97 bzero(&foo, sizeof(VFoo));98 bzero(&foo, sizeof(CVFoo));99 bzero(ps, sizeof(*ps));100 bzero(ps2, sizeof(*ps2));101 bzero(ps2, sizeof(typeof(*ps2)));102 bzero(arr, sizeof(arr));103 bzero(parr, sizeof(parr));104 105 memcpy(&foo, &const_foo, sizeof(Foo));106 memcpy((void*)&s, 0, sizeof(&s));107 memcpy(0, (void*)&s, sizeof(&s));108 char *cptr;109 memcpy(&cptr, buffer, sizeof(cptr));110 memcpy((char*)&cptr, buffer, sizeof(cptr));111 112 CFooRef cfoo = foo;113 memcpy(&foo, &cfoo, sizeof(Foo));114 115 memcpy(0, &arr, sizeof(arr));116 typedef char Buff[8];117 memcpy(0, &arr, sizeof(Buff));118 119 unsigned char* puc;120 bit_cast<char*>(puc);121 122 float* pf;123 bit_cast<int*>(pf);124 125 int iarr[14];126 memset(&iarr[0], 0, sizeof iarr);127 memset(iarr, 0, sizeof iarr);128 bzero(&iarr[0], sizeof iarr);129 bzero(iarr, sizeof iarr);130 131 int* iparr[14];132 memset(&iparr[0], 0, sizeof iparr);133 memset(iparr, 0, sizeof iparr);134 bzero(&iparr[0], sizeof iparr);135 bzero(iparr, sizeof iparr);136 137 memset(m, 0, sizeof(Mat));138 bzero(m, sizeof(Mat));139 140 // Copy to raw buffer shouldn't warn either141 memcpy(&foo, &arr, sizeof(Foo));142 memcpy(&arr, &foo, sizeof(Foo));143 144 // Shouldn't warn, and shouldn't crash either.145 memset(({146 if (0) {}147 while (0) {}148 for (;;) {}149 &s;150 }), 0, sizeof(s));151 152 bzero(({153 if (0) {}154 while (0) {}155 for (;;) {}156 &s;157 }), sizeof(s));158}159 160namespace ns {161void memset(void* s, char c, int n);162void bzero(void* s, int n);163void f(int* i) {164 memset(i, 0, sizeof(i));165 bzero(i, sizeof(i));166}167}168 169extern "C" int strncmp(const char *s1, const char *s2, unsigned n);170extern "C" int strncasecmp(const char *s1, const char *s2, unsigned n);171extern "C" char *strncpy(char *det, const char *src, unsigned n);172extern "C" char *strncat(char *dst, const char *src, unsigned n);173extern "C" char *strndup(const char *src, unsigned n);174 175void strcpy_and_friends() {176 const char* FOO = "<- should be an array instead";177 const char* BAR = "<- this, too";178 179 strncmp(FOO, BAR, sizeof(FOO)); // \180 // 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?}}181 strncasecmp(FOO, BAR, sizeof(FOO)); // \182 // 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?}}183 184 char buff[80];185 186 strncpy(buff, BAR, sizeof(BAR)); // \187 // 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?}}188 strndup(FOO, sizeof(FOO)); // \189 // 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?}}190}191