1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -Wstrlcpy-strlcat-size -verify -fsyntax-only %s
2*f4a2713aSLionel Sambuc
3*f4a2713aSLionel Sambuc typedef __SIZE_TYPE__ size_t;
4*f4a2713aSLionel Sambuc size_t strlcpy (char * restrict dst, const char * restrict src, size_t size);
5*f4a2713aSLionel Sambuc size_t strlcat (char * restrict dst, const char * restrict src, size_t size);
6*f4a2713aSLionel Sambuc size_t strlen (const char *s);
7*f4a2713aSLionel Sambuc
8*f4a2713aSLionel Sambuc char s1[100];
9*f4a2713aSLionel Sambuc char s2[200];
10*f4a2713aSLionel Sambuc char * s3;
11*f4a2713aSLionel Sambuc
12*f4a2713aSLionel Sambuc struct {
13*f4a2713aSLionel Sambuc char f1[100];
14*f4a2713aSLionel Sambuc char f2[100][3];
15*f4a2713aSLionel Sambuc } s4, **s5;
16*f4a2713aSLionel Sambuc
17*f4a2713aSLionel Sambuc int x;
18*f4a2713aSLionel Sambuc
f(void)19*f4a2713aSLionel Sambuc void f(void)
20*f4a2713aSLionel Sambuc {
21*f4a2713aSLionel Sambuc strlcpy(s1, s2, sizeof(s1)); // no warning
22*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc }
29*f4a2713aSLionel Sambuc
30*f4a2713aSLionel Sambuc // Don't issue FIXIT for flexible arrays.
31*f4a2713aSLionel Sambuc struct S {
32*f4a2713aSLionel Sambuc int y;
33*f4a2713aSLionel Sambuc char x[];
34*f4a2713aSLionel Sambuc };
35*f4a2713aSLionel Sambuc
flexible_arrays(struct S * s)36*f4a2713aSLionel Sambuc void flexible_arrays(struct S *s) {
37*f4a2713aSLionel Sambuc char str[] = "hi";
38*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc }
40*f4a2713aSLionel Sambuc
41*f4a2713aSLionel Sambuc // Don't issue FIXIT for destinations of size 1.
size_1()42*f4a2713aSLionel Sambuc void size_1() {
43*f4a2713aSLionel Sambuc char z[1];
44*f4a2713aSLionel Sambuc char str[] = "hi";
45*f4a2713aSLionel Sambuc
46*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc }
48*f4a2713aSLionel Sambuc
49*f4a2713aSLionel Sambuc // Support VLAs.
vlas(int size)50*f4a2713aSLionel Sambuc void vlas(int size) {
51*f4a2713aSLionel Sambuc char z[size];
52*f4a2713aSLionel Sambuc char str[] = "hi";
53*f4a2713aSLionel Sambuc
54*f4a2713aSLionel Sambuc 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*f4a2713aSLionel Sambuc }
56