blob: c000b4477382fd131564e66acca34e035955b54f [file] [log] [blame]
Nico Webere4a1c642011-06-14 16:14:58 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
2//
3extern "C" void *memset(void *, int, unsigned);
4extern "C" void *memmove(void *s1, const void *s2, unsigned n);
5extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
6
7struct S {int a, b, c, d;};
8typedef S* PS;
9
10struct Foo {};
11typedef const Foo& CFooRef;
12typedef const Foo CFoo;
13typedef volatile Foo VFoo;
14typedef const volatile Foo CVFoo;
15
16typedef double Mat[4][4];
17
18template <class Dest, class Source>
19inline 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
26void f(char fake_array[8], Mat m, const Foo& const_foo) {
27 S s;
28 S* ps = &s;
29 PS ps2 = &s;
30 char arr[5];
31 char* parr[5];
32 Foo foo;
33
34 /* Should warn */
35 memset(&s, 0, sizeof(&s)); // \
36 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}}
37 memset(ps, 0, sizeof(ps)); // \
38 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}}
39 memset(ps2, 0, sizeof(ps2)); // \
40 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
41 memset(ps2, 0, sizeof(typeof(ps2))); // \
42 // expected-warning {{the argument to sizeof is pointer type 'typeof (ps2)' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
43 memset(ps2, 0, sizeof(PS)); // \
44 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
45 memset(fake_array, 0, sizeof(fake_array)); // \
46 // expected-warning {{the argument to sizeof is pointer type 'char *', expected 'char' to match first argument to 'memset'}}
47
48 memcpy(&s, 0, sizeof(&s)); // \
49 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memcpy'}}
50 memcpy(0, &s, sizeof(&s)); // \
51 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match second argument to 'memcpy'}}
52
53 /* Shouldn't warn */
54 memset((void*)&s, 0, sizeof(&s));
55 memset(&s, 0, sizeof(s));
56 memset(&s, 0, sizeof(S));
57 memset(&s, 0, sizeof(const S));
58 memset(&s, 0, sizeof(volatile S));
59 memset(&s, 0, sizeof(volatile const S));
60 memset(&foo, 0, sizeof(CFoo));
61 memset(&foo, 0, sizeof(VFoo));
62 memset(&foo, 0, sizeof(CVFoo));
63 memset(ps, 0, sizeof(*ps));
64 memset(ps2, 0, sizeof(*ps2));
65 memset(ps2, 0, sizeof(typeof(*ps2)));
66 memset(arr, 0, sizeof(arr));
67 memset(parr, 0, sizeof(parr));
68
69 memcpy(&foo, &const_foo, sizeof(Foo));
70 memcpy((void*)&s, 0, sizeof(&s));
71 memcpy(0, (void*)&s, sizeof(&s));
72
73 CFooRef cfoo = foo;
74 memcpy(&foo, &cfoo, sizeof(Foo));
75
76 memcpy(0, &arr, sizeof(arr));
77 typedef char Buff[8];
78 memcpy(0, &arr, sizeof(Buff));
79
80 unsigned char* puc;
81 bit_cast<char*>(puc);
82
83 float* pf;
84 bit_cast<int*>(pf);
85
86 int iarr[14];
87 memset(&iarr[0], 0, sizeof iarr);
88
89 int* iparr[14];
90 memset(&iparr[0], 0, sizeof iparr);
91
92 memset(m, 0, sizeof(Mat));
93
94 // Copy to raw buffer shouldn't warn either
95 memcpy(&foo, &arr, sizeof(Foo));
96 memcpy(&arr, &foo, sizeof(Foo));
97}