blob: b334500ef5c63af5426c16c53c1291f214cd8a90 [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 Carruthc7b993b2011-06-16 04:13:47 +000026void f(Mat m, const Foo& const_foo, char *buffer) {
Nico Webere4a1c642011-06-14 16:14:58 +000027 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'}}
Nico Webere4a1c642011-06-14 16:14:58 +000045
46 memcpy(&s, 0, sizeof(&s)); // \
47 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match first argument to 'memcpy'}}
48 memcpy(0, &s, sizeof(&s)); // \
49 // expected-warning {{the argument to sizeof is pointer type 'S *', expected 'S' to match second argument to 'memcpy'}}
50
51 /* Shouldn't warn */
52 memset((void*)&s, 0, sizeof(&s));
53 memset(&s, 0, sizeof(s));
54 memset(&s, 0, sizeof(S));
55 memset(&s, 0, sizeof(const S));
56 memset(&s, 0, sizeof(volatile S));
57 memset(&s, 0, sizeof(volatile const S));
58 memset(&foo, 0, sizeof(CFoo));
59 memset(&foo, 0, sizeof(VFoo));
60 memset(&foo, 0, sizeof(CVFoo));
61 memset(ps, 0, sizeof(*ps));
62 memset(ps2, 0, sizeof(*ps2));
63 memset(ps2, 0, sizeof(typeof(*ps2)));
64 memset(arr, 0, sizeof(arr));
65 memset(parr, 0, sizeof(parr));
66
67 memcpy(&foo, &const_foo, sizeof(Foo));
68 memcpy((void*)&s, 0, sizeof(&s));
69 memcpy(0, (void*)&s, sizeof(&s));
Chandler Carruthc7b993b2011-06-16 04:13:47 +000070 char *cptr;
71 memcpy(&cptr, buffer, sizeof(cptr));
72 memcpy((char*)&cptr, buffer, sizeof(cptr));
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}