1 // RUN: %clang_cc1 -Wstrncat-size -verify -fsyntax-only %s
2 // RUN: %clang_cc1 -DUSE_BUILTINS -Wstrncat-size -verify -fsyntax-only %s
3 // RUN: %clang_cc1 -Wstrncat-size -fixit -x c %s
4 // RUN: %clang_cc1 -DUSE_BUILTINS -Wstrncat-size -fixit -x c %s
6 typedef __SIZE_TYPE__
size_t;
7 size_t strlen (const char *s
);
10 # define BUILTIN(f) __builtin_ ## f
15 #define strncat BUILTIN(strncat)
16 char *strncat(char *restrict s1
, const char *restrict s2
, size_t n
);
27 void test(char *src
) {
30 strncat(dest
, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest
) - strlen(dest
) - 1); // no-warning
31 strncat(dest
, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest
) - 1); // no-warning - the code might assume that dest is empty
33 strncat(dest
, src
, sizeof(src
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
35 strncat(dest
, src
, sizeof(src
) - 1); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
37 strncat(dest
, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest
)); // expected-warning{{the value of the size argument in 'strncat' is too large, might lead to a buffer overflow}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
39 strncat(dest
, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest
) - strlen(dest
)); // expected-warning{{the value of the size argument in 'strncat' is too large, might lead to a buffer overflow}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
41 strncat((*s5
)->f2
[x
], s2
, sizeof(s2
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
42 strncat(s1
+3, s2
, sizeof(s2
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-warning {{strncat' size argument is too large; destination buffer has size 97, but size argument is 200}}
43 strncat(s4
.f1
, s2
, sizeof(s2
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
46 // Don't issue FIXIT for flexible arrays.
52 void flexible_arrays(struct S
*s
) {
54 strncat(s
->x
, str
, sizeof(str
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}}
57 // Don't issue FIXIT for destinations of size 1.
62 strncat(z
, str
, sizeof(z
)); // expected-warning{{the value of the size argument to 'strncat' is wrong}}
70 strncat(z
, str
, sizeof(str
)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
73 // Non-array type gets a different error message.
74 void f(char* s
, char* d
) {
75 strncat(d
, s
, sizeof(d
)); // expected-warning {{the value of the size argument to 'strncat' is wrong}}