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