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