blob: 90ac50472e98df065f9a4563a5f32513962bb8df [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;
Chandler Carruth000d4282011-06-16 09:09:40 +000033 char* heap_buffer = new char[42];
Nico Webere4a1c642011-06-14 16:14:58 +000034
35 /* Should warn */
36 memset(&s, 0, sizeof(&s)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000037 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
Nico Webere4a1c642011-06-14 16:14:58 +000038 memset(ps, 0, sizeof(ps)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000039 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
Nico Webere4a1c642011-06-14 16:14:58 +000040 memset(ps2, 0, sizeof(ps2)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000041 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
Nico Webere4a1c642011-06-14 16:14:58 +000042 memset(ps2, 0, sizeof(typeof(ps2))); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000043 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
Nico Webere4a1c642011-06-14 16:14:58 +000044 memset(ps2, 0, sizeof(PS)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000045 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
46 memset(heap_buffer, 0, sizeof(heap_buffer)); // \
47 // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
Nico Webere4a1c642011-06-14 16:14:58 +000048
49 memcpy(&s, 0, sizeof(&s)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000050 // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination}}
Nico Webere4a1c642011-06-14 16:14:58 +000051 memcpy(0, &s, sizeof(&s)); // \
Chandler Carruth000d4282011-06-16 09:09:40 +000052 // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}}
Nico Webere4a1c642011-06-14 16:14:58 +000053
54 /* Shouldn't warn */
55 memset((void*)&s, 0, sizeof(&s));
56 memset(&s, 0, sizeof(s));
57 memset(&s, 0, sizeof(S));
58 memset(&s, 0, sizeof(const S));
59 memset(&s, 0, sizeof(volatile S));
60 memset(&s, 0, sizeof(volatile const S));
61 memset(&foo, 0, sizeof(CFoo));
62 memset(&foo, 0, sizeof(VFoo));
63 memset(&foo, 0, sizeof(CVFoo));
64 memset(ps, 0, sizeof(*ps));
65 memset(ps2, 0, sizeof(*ps2));
66 memset(ps2, 0, sizeof(typeof(*ps2)));
67 memset(arr, 0, sizeof(arr));
68 memset(parr, 0, sizeof(parr));
69
70 memcpy(&foo, &const_foo, sizeof(Foo));
71 memcpy((void*)&s, 0, sizeof(&s));
72 memcpy(0, (void*)&s, sizeof(&s));
Chandler Carruthc7b993b2011-06-16 04:13:47 +000073 char *cptr;
74 memcpy(&cptr, buffer, sizeof(cptr));
75 memcpy((char*)&cptr, buffer, sizeof(cptr));
Nico Webere4a1c642011-06-14 16:14:58 +000076
77 CFooRef cfoo = foo;
78 memcpy(&foo, &cfoo, sizeof(Foo));
79
80 memcpy(0, &arr, sizeof(arr));
81 typedef char Buff[8];
82 memcpy(0, &arr, sizeof(Buff));
83
84 unsigned char* puc;
85 bit_cast<char*>(puc);
86
87 float* pf;
88 bit_cast<int*>(pf);
89
90 int iarr[14];
91 memset(&iarr[0], 0, sizeof iarr);
92
93 int* iparr[14];
94 memset(&iparr[0], 0, sizeof iparr);
95
96 memset(m, 0, sizeof(Mat));
97
98 // Copy to raw buffer shouldn't warn either
99 memcpy(&foo, &arr, sizeof(Foo));
100 memcpy(&arr, &foo, sizeof(Foo));
101}