string.c revision 19c5dd120e42b1ba0642309a185c70f4a41aadbd
1// RUN: %clang_cc1 -analyze -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 3// RUN: %clang_cc1 -analyze -DVARIANT -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 5 6//===----------------------------------------------------------------------=== 7// Declarations 8//===----------------------------------------------------------------------=== 9 10// Some functions are so similar to each other that they follow the same code 11// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is 12// defined, make sure to use the variants instead to make sure they are still 13// checked by the analyzer. 14 15// Some functions are implemented as builtins. These should be #defined as 16// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined. 17 18// Functions that have variants and are also availabe as builtins should be 19// declared carefully! See memcpy() for an example. 20 21#ifdef USE_BUILTINS 22# define BUILTIN(f) __builtin_ ## f 23#else /* USE_BUILTINS */ 24# define BUILTIN(f) f 25#endif /* USE_BUILTINS */ 26 27typedef typeof(sizeof(int)) size_t; 28 29//===----------------------------------------------------------------------=== 30// strlen() 31//===----------------------------------------------------------------------=== 32 33#define strlen BUILTIN(strlen) 34size_t strlen(const char *s); 35 36void strlen_constant0() { 37 if (strlen("123") != 3) 38 (void)*(char*)0; // expected-warning{{never executed}} 39} 40 41void strlen_constant1() { 42 const char *a = "123"; 43 if (strlen(a) != 3) 44 (void)*(char*)0; // expected-warning{{never executed}} 45} 46 47void strlen_constant2(char x) { 48 char a[] = "123"; 49 a[0] = x; 50 if (strlen(a) != 3) 51 (void)*(char*)0; // expected-warning{{null}} 52} 53 54size_t strlen_null() { 55 return strlen(0); // expected-warning{{Null pointer argument in call to byte string function}} 56} 57 58size_t strlen_fn() { 59 return strlen((char*)&strlen_fn); // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}} 60} 61 62size_t strlen_nonloc() { 63label: 64 return strlen((char*)&&label); // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}} 65} 66