1 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s
3 extern "C" void *bzero(void *, unsigned);
4 extern "C" void *memset(void *, int, unsigned);
5 extern "C" void *memmove(void *s1
, const void *s2
, unsigned n
);
6 extern "C" void *memcpy(void *s1
, const void *s2
, unsigned n
);
7 extern "C" void *memcmp(void *s1
, const void *s2
, unsigned n
);
9 struct S
{int a
, b
, c
, d
;};
13 typedef const Foo
& CFooRef
;
14 typedef const Foo CFoo
;
15 typedef volatile Foo VFoo
;
16 typedef const volatile Foo CVFoo
;
18 typedef double Mat
[4][4];
20 template <class Dest
, class Source
>
21 inline Dest
bit_cast(const Source
& source
) {
23 memcpy(&dest
, &source
, sizeof(dest
));
27 // http://www.lysator.liu.se/c/c-faq/c-2.html#2-6
28 void f(Mat m
, const Foo
& const_foo
, char *buffer
) {
35 char* heap_buffer
= new char[42];
38 memset(&s
, 0, sizeof(&s
)); // \
39 // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
40 memset(ps
, 0, sizeof(ps
)); // \
41 // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
42 memset(ps2
, 0, sizeof(ps2
)); // \
43 // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
44 memset(ps2
, 0, sizeof(typeof(ps2
))); // \
45 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
46 memset(ps2
, 0, sizeof(PS
)); // \
47 // expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
48 memset(heap_buffer
, 0, sizeof(heap_buffer
)); // \
49 // expected-warning {{'memset' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
51 bzero(&s
, sizeof(&s
)); // \
52 // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
53 bzero(ps
, sizeof(ps
)); // \
54 // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
55 bzero(ps2
, sizeof(ps2
)); // \
56 // expected-warning {{'bzero' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
57 bzero(ps2
, sizeof(typeof(ps2
))); // \
58 // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}
59 bzero(ps2
, sizeof(PS
)); // \
60 // expected-warning {{argument to 'sizeof' in 'bzero' call is the same pointer type}}
61 bzero(heap_buffer
, sizeof(heap_buffer
)); // \
62 // expected-warning {{'bzero' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
64 memcpy(&s
, 0, sizeof(&s
)); // \
65 // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
66 memcpy(0, &s
, sizeof(&s
)); // \
67 // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
69 memmove(ps
, 0, sizeof(ps
)); // \
70 // expected-warning {{'memmove' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
71 memcmp(ps
, 0, sizeof(ps
)); // \
72 // expected-warning {{'memcmp' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
75 memset((void*)&s
, 0, sizeof(&s
));
76 memset(&s
, 0, sizeof(s
));
77 memset(&s
, 0, sizeof(S
));
78 memset(&s
, 0, sizeof(const S
));
79 memset(&s
, 0, sizeof(volatile S
));
80 memset(&s
, 0, sizeof(volatile const S
));
81 memset(&foo
, 0, sizeof(CFoo
));
82 memset(&foo
, 0, sizeof(VFoo
));
83 memset(&foo
, 0, sizeof(CVFoo
));
84 memset(ps
, 0, sizeof(*ps
));
85 memset(ps2
, 0, sizeof(*ps2
));
86 memset(ps2
, 0, sizeof(typeof(*ps2
)));
87 memset(arr
, 0, sizeof(arr
));
88 memset(parr
, 0, sizeof(parr
));
90 bzero((void*)&s
, sizeof(&s
));
93 bzero(&s
, sizeof(const S
));
94 bzero(&s
, sizeof(volatile S
));
95 bzero(&s
, sizeof(volatile const S
));
96 bzero(&foo
, sizeof(CFoo
));
97 bzero(&foo
, sizeof(VFoo
));
98 bzero(&foo
, sizeof(CVFoo
));
99 bzero(ps
, sizeof(*ps
));
100 bzero(ps2
, sizeof(*ps2
));
101 bzero(ps2
, sizeof(typeof(*ps2
)));
102 bzero(arr
, sizeof(arr
));
103 bzero(parr
, sizeof(parr
));
105 memcpy(&foo
, &const_foo
, sizeof(Foo
));
106 memcpy((void*)&s
, 0, sizeof(&s
));
107 memcpy(0, (void*)&s
, sizeof(&s
));
109 memcpy(&cptr
, buffer
, sizeof(cptr
));
110 memcpy((char*)&cptr
, buffer
, sizeof(cptr
));
113 memcpy(&foo
, &cfoo
, sizeof(Foo
));
115 memcpy(0, &arr
, sizeof(arr
));
116 typedef char Buff
[8];
117 memcpy(0, &arr
, sizeof(Buff
));
120 bit_cast
<char*>(puc
);
126 memset(&iarr
[0], 0, sizeof iarr
);
127 memset(iarr
, 0, sizeof iarr
);
128 bzero(&iarr
[0], sizeof iarr
);
129 bzero(iarr
, sizeof iarr
);
132 memset(&iparr
[0], 0, sizeof iparr
);
133 memset(iparr
, 0, sizeof iparr
);
134 bzero(&iparr
[0], sizeof iparr
);
135 bzero(iparr
, sizeof iparr
);
137 memset(m
, 0, sizeof(Mat
));
138 bzero(m
, sizeof(Mat
));
140 // Copy to raw buffer shouldn't warn either
141 memcpy(&foo
, &arr
, sizeof(Foo
));
142 memcpy(&arr
, &foo
, sizeof(Foo
));
144 // Shouldn't warn, and shouldn't crash either.
161 void memset(void* s
, char c
, int n
);
162 void bzero(void* s
, int n
);
164 memset(i
, 0, sizeof(i
));
169 extern "C" int strncmp(const char *s1
, const char *s2
, unsigned n
);
170 extern "C" int strncasecmp(const char *s1
, const char *s2
, unsigned n
);
171 extern "C" char *strncpy(char *det
, const char *src
, unsigned n
);
172 extern "C" char *strncat(char *dst
, const char *src
, unsigned n
);
173 extern "C" char *strndup(const char *src
, unsigned n
);
175 void strcpy_and_friends() {
176 const char* FOO
= "<- should be an array instead";
177 const char* BAR
= "<- this, too";
179 strncmp(FOO
, BAR
, sizeof(FOO
)); // \
180 // expected-warning {{'strncmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
181 strncasecmp(FOO
, BAR
, sizeof(FOO
)); // \
182 // expected-warning {{'strncasecmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
186 strncpy(buff
, BAR
, sizeof(BAR
)); // \
187 // expected-warning {{'strncpy' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
188 strndup(FOO
, sizeof(FOO
)); // \
189 // expected-warning {{'strndup' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}