1c36bedc90c687caa71748480c60707ea4608b092Anna Zaks// RUN: %clang_cc1 -Wstrncat-size -verify -fsyntax-only %s 2afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks// RUN: %clang_cc1 -DUSE_BUILTINS -Wstrncat-size -verify -fsyntax-only %s 3afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks// RUN: %clang_cc1 -fsyntax-only -Wstrncat-size -fixit -x c %s 4afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks// RUN: %clang_cc1 -DUSE_BUILTINS -fsyntax-only -Wstrncat-size -fixit -x c %s 5c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 6c36bedc90c687caa71748480c60707ea4608b092Anna Zakstypedef __SIZE_TYPE__ size_t; 7c36bedc90c687caa71748480c60707ea4608b092Anna Zakssize_t strlen (const char *s); 8c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 9afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks#ifdef USE_BUILTINS 10afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks# define BUILTIN(f) __builtin_ ## f 11afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks#else 12afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks# define BUILTIN(f) f 13afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks#endif 14afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks 15afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks#define strncat BUILTIN(strncat) 16afdb041308bca3e875b23e7a22d879e9039bff03Anna Zakschar *strncat(char *restrict s1, const char *restrict s2, size_t n); 17afdb041308bca3e875b23e7a22d879e9039bff03Anna Zaks 18c36bedc90c687caa71748480c60707ea4608b092Anna Zaksstruct { 19c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char f1[100]; 20c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char f2[100][3]; 21c36bedc90c687caa71748480c60707ea4608b092Anna Zaks} s4, **s5; 22c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 23c36bedc90c687caa71748480c60707ea4608b092Anna Zakschar s1[100]; 24c36bedc90c687caa71748480c60707ea4608b092Anna Zakschar s2[200]; 25c36bedc90c687caa71748480c60707ea4608b092Anna Zaksint x; 26c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 27c36bedc90c687caa71748480c60707ea4608b092Anna Zaksvoid test(char *src) { 28c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char dest[10]; 29c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 30c36bedc90c687caa71748480c60707ea4608b092Anna Zaks strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest) - 1); // no-warning 31c36bedc90c687caa71748480c60707ea4608b092Anna Zaks strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - 1); // no-warning - the code might assume that dest is empty 32c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 33c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 34c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 35c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 36c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 37c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 38c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 39c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 40c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 41c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 42c36bedc90c687caa71748480c60707ea4608b092Anna Zaks strncat(s1+3, s2, sizeof(s2)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} 43c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 44c36bedc90c687caa71748480c60707ea4608b092Anna Zaks} 45c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 46c36bedc90c687caa71748480c60707ea4608b092Anna Zaks// Don't issue FIXIT for flexible arrays. 47c36bedc90c687caa71748480c60707ea4608b092Anna Zaksstruct S { 48c36bedc90c687caa71748480c60707ea4608b092Anna Zaks int y; 49c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char x[]; 50c36bedc90c687caa71748480c60707ea4608b092Anna Zaks}; 51c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 52c36bedc90c687caa71748480c60707ea4608b092Anna Zaksvoid flexible_arrays(struct S *s) { 53c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char str[] = "hi"; 54c36bedc90c687caa71748480c60707ea4608b092Anna Zaks strncat(s->x, str, sizeof(str)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} 55c36bedc90c687caa71748480c60707ea4608b092Anna Zaks} 56c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 57c36bedc90c687caa71748480c60707ea4608b092Anna Zaks// Don't issue FIXIT for destinations of size 1. 58c36bedc90c687caa71748480c60707ea4608b092Anna Zaksvoid size_1() { 59c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char z[1]; 60c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char str[] = "hi"; 61c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 620f38acee92014cb15af980808f87144e5564031dAnna Zaks strncat(z, str, sizeof(z)); // expected-warning{{the value of the size argument to 'strncat' is wrong}} 63c36bedc90c687caa71748480c60707ea4608b092Anna Zaks} 64c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 65c36bedc90c687caa71748480c60707ea4608b092Anna Zaks// Support VLAs. 66c36bedc90c687caa71748480c60707ea4608b092Anna Zaksvoid vlas(int size) { 67c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char z[size]; 68c36bedc90c687caa71748480c60707ea4608b092Anna Zaks char str[] = "hi"; 69c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 70c36bedc90c687caa71748480c60707ea4608b092Anna Zaks 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}} 71c36bedc90c687caa71748480c60707ea4608b092Anna Zaks} 720f38acee92014cb15af980808f87144e5564031dAnna Zaks 730f38acee92014cb15af980808f87144e5564031dAnna Zaks// Non-array type gets a different error message. 740f38acee92014cb15af980808f87144e5564031dAnna Zaksvoid f(char* s, char* d) { 750f38acee92014cb15af980808f87144e5564031dAnna Zaks strncat(d, s, sizeof(d)); // expected-warning {{the value of the size argument to 'strncat' is wrong}} 760f38acee92014cb15af980808f87144e5564031dAnna Zaks} 77