blob: 167f05f3daff98775ba182bc3cc1448fcebc0464 [file] [log] [blame]
Nico Weber55080a72011-06-15 04:50:13 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s
Nico Webere4a1c642011-06-14 16:14:58 +00002//
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
Chandler Carruth5546e692011-06-16 02:00:04 +000026void f(Mat m, const Foo& const_foo) {
Nico Webere4a1c642011-06-14 16:14:58 +000027 S s;
28 S* ps = &s;
29 PS ps2 = &s;
Chandler Carruth5546e692011-06-16 02:00:04 +000030 char c = 42;
Nico Webere4a1c642011-06-14 16:14:58 +000031 char arr[5];
32 char* parr[5];
33 Foo foo;
34
35 /* Should warn */
36 memset(&s, 0, sizeof(&s)); // \
37 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}}
38 memset(ps, 0, sizeof(ps)); // \
39 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memset'}}
40 memset(ps2, 0, sizeof(ps2)); // \
41 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
42 memset(ps2, 0, sizeof(typeof(ps2))); // \
43 // expected-warning {{the argument to sizeof is pointer type 'typeof (ps2)' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
44 memset(ps2, 0, sizeof(PS)); // \
45 // expected-warning {{the argument to sizeof is pointer type 'PS' (aka 'S *'), expected 'S' to match first argument to 'memset'}}
Nico Webere4a1c642011-06-14 16:14:58 +000046
47 memcpy(&s, 0, sizeof(&s)); // \
48 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memcpy'}}
49 memcpy(0, &s, sizeof(&s)); // \
50 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match second argument to 'memcpy'}}
51
52 /* Shouldn't warn */
53 memset((void*)&s, 0, sizeof(&s));
54 memset(&s, 0, sizeof(s));
55 memset(&s, 0, sizeof(S));
56 memset(&s, 0, sizeof(const S));
57 memset(&s, 0, sizeof(volatile S));
58 memset(&s, 0, sizeof(volatile const S));
59 memset(&foo, 0, sizeof(CFoo));
60 memset(&foo, 0, sizeof(VFoo));
61 memset(&foo, 0, sizeof(CVFoo));
62 memset(ps, 0, sizeof(*ps));
63 memset(ps2, 0, sizeof(*ps2));
64 memset(ps2, 0, sizeof(typeof(*ps2)));
65 memset(arr, 0, sizeof(arr));
66 memset(parr, 0, sizeof(parr));
67
68 memcpy(&foo, &const_foo, sizeof(Foo));
69 memcpy((void*)&s, 0, sizeof(&s));
70 memcpy(0, (void*)&s, sizeof(&s));
Chandler Carruth5546e692011-06-16 02:00:04 +000071 memcpy(&parr[3], &c, sizeof(&c));
72 memcpy((char*)&parr[3], &c, sizeof(&c));
Nico Webere4a1c642011-06-14 16:14:58 +000073
74 CFooRef cfoo = foo;
75 memcpy(&foo, &cfoo, sizeof(Foo));
76
77 memcpy(0, &arr, sizeof(arr));
78 typedef char Buff[8];
79 memcpy(0, &arr, sizeof(Buff));
80
81 unsigned char* puc;
82 bit_cast<char*>(puc);
83
84 float* pf;
85 bit_cast<int*>(pf);
86
87 int iarr[14];
88 memset(&iarr[0], 0, sizeof iarr);
89
90 int* iparr[14];
91 memset(&iparr[0], 0, sizeof iparr);
92
93 memset(m, 0, sizeof(Mat));
94
95 // Copy to raw buffer shouldn't warn either
96 memcpy(&foo, &arr, sizeof(Foo));
97 memcpy(&arr, &foo, sizeof(Foo));
98}