1*67e74705SXin Li // RUN: %clang_cc1 -Wstrlcpy-strlcat-size -verify -fsyntax-only %s
2*67e74705SXin Li
3*67e74705SXin Li typedef __SIZE_TYPE__ size_t;
4*67e74705SXin Li size_t strlcpy (char * restrict dst, const char * restrict src, size_t size);
5*67e74705SXin Li size_t strlcat (char * restrict dst, const char * restrict src, size_t size);
6*67e74705SXin Li size_t strlen (const char *s);
7*67e74705SXin Li
8*67e74705SXin Li char s1[100];
9*67e74705SXin Li char s2[200];
10*67e74705SXin Li char * s3;
11*67e74705SXin Li
12*67e74705SXin Li struct {
13*67e74705SXin Li char f1[100];
14*67e74705SXin Li char f2[100][3];
15*67e74705SXin Li } s4, **s5;
16*67e74705SXin Li
17*67e74705SXin Li int x;
18*67e74705SXin Li
f(void)19*67e74705SXin Li void f(void)
20*67e74705SXin Li {
21*67e74705SXin Li strlcpy(s1, s2, sizeof(s1)); // no warning
22*67e74705SXin Li strlcpy(s1, s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
23*67e74705SXin Li strlcpy(s1, s3, strlen(s3)+1); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
24*67e74705SXin Li strlcat(s2, s3, sizeof(s3)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
25*67e74705SXin Li strlcpy(s4.f1, s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
26*67e74705SXin Li strlcpy((*s5)->f2[x], s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
27*67e74705SXin Li strlcpy(s1+3, s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}}
28*67e74705SXin Li }
29*67e74705SXin Li
30*67e74705SXin Li // Don't issue FIXIT for flexible arrays.
31*67e74705SXin Li struct S {
32*67e74705SXin Li int y;
33*67e74705SXin Li char x[];
34*67e74705SXin Li };
35*67e74705SXin Li
flexible_arrays(struct S * s)36*67e74705SXin Li void flexible_arrays(struct S *s) {
37*67e74705SXin Li char str[] = "hi";
38*67e74705SXin Li strlcpy(s->x, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}}
39*67e74705SXin Li }
40*67e74705SXin Li
41*67e74705SXin Li // Don't issue FIXIT for destinations of size 1.
size_1()42*67e74705SXin Li void size_1() {
43*67e74705SXin Li char z[1];
44*67e74705SXin Li char str[] = "hi";
45*67e74705SXin Li
46*67e74705SXin Li strlcpy(z, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}}
47*67e74705SXin Li }
48*67e74705SXin Li
49*67e74705SXin Li // Support VLAs.
vlas(int size)50*67e74705SXin Li void vlas(int size) {
51*67e74705SXin Li char z[size];
52*67e74705SXin Li char str[] = "hi";
53*67e74705SXin Li
54*67e74705SXin Li strlcpy(z, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}}
55*67e74705SXin Li }
56