bstring.c revision d325ffb9cbd26b6a3f219d115191d9a00b6dea8c
1// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s 4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -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// memcpy() 31//===----------------------------------------------------------------------=== 32 33#ifdef VARIANT 34 35#define __memcpy_chk BUILTIN(__memcpy_chk) 36void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 37 size_t destlen); 38 39#define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1) 40 41#else /* VARIANT */ 42 43#define memcpy BUILTIN(memcpy) 44void *memcpy(void *restrict s1, const void *restrict s2, size_t n); 45 46#endif /* VARIANT */ 47 48 49void memcpy0 () { 50 char src[] = {1, 2, 3, 4}; 51 char dst[4]; 52 53 memcpy(dst, src, 4); // no-warning 54 55 if (memcpy(dst, src, 4) != dst) { 56 (void)*(char*)0; // no-warning -- should be unreachable 57 } 58} 59 60void memcpy1 () { 61 char src[] = {1, 2, 3, 4}; 62 char dst[10]; 63 64 memcpy(dst, src, 5); // expected-warning{{out-of-bound}} 65} 66 67void memcpy2 () { 68 char src[] = {1, 2, 3, 4}; 69 char dst[1]; 70 71 memcpy(dst, src, 4); // expected-warning{{out-of-bound}} 72} 73 74void memcpy3 () { 75 char src[] = {1, 2, 3, 4}; 76 char dst[3]; 77 78 memcpy(dst+1, src+2, 2); // no-warning 79} 80 81void memcpy4 () { 82 char src[] = {1, 2, 3, 4}; 83 char dst[10]; 84 85 memcpy(dst+2, src+2, 3); // expected-warning{{out-of-bound}} 86} 87 88void memcpy5() { 89 char src[] = {1, 2, 3, 4}; 90 char dst[3]; 91 92 memcpy(dst+2, src+2, 2); // expected-warning{{out-of-bound}} 93} 94 95void memcpy6() { 96 int a[4] = {0}; 97 memcpy(a, a, 8); // expected-warning{{overlapping}} 98} 99 100void memcpy7() { 101 int a[4] = {0}; 102 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 103} 104 105void memcpy8() { 106 int a[4] = {0}; 107 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 108} 109 110void memcpy9() { 111 int a[4] = {0}; 112 memcpy(a+2, a+1, 4); // no-warning 113 memcpy(a+1, a+2, 4); // no-warning 114} 115 116void memcpy10() { 117 char a[4] = {0}; 118 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} 119} 120 121void memcpy11() { 122 char a[4] = {0}; 123 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} 124} 125 126void memcpy12() { 127 char a[4] = {0}; 128 memcpy(0, a, 0); // no-warning 129 memcpy(a, 0, 0); // no-warning 130} 131 132//===----------------------------------------------------------------------=== 133// memmove() 134//===----------------------------------------------------------------------=== 135 136#ifdef VARIANT 137 138#define __memmove_chk BUILTIN(__memmove_chk) 139void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 140 141#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 142 143#else /* VARIANT */ 144 145#define memmove BUILTIN(memmove) 146void *memmove(void *s1, const void *s2, size_t n); 147 148#endif /* VARIANT */ 149 150 151void memmove0 () { 152 char src[] = {1, 2, 3, 4}; 153 char dst[4]; 154 155 memmove(dst, src, 4); // no-warning 156 157 if (memmove(dst, src, 4) != dst) { 158 (void)*(char*)0; // no-warning -- should be unreachable 159 } 160} 161 162void memmove1 () { 163 char src[] = {1, 2, 3, 4}; 164 char dst[10]; 165 166 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 167} 168 169void memmove2 () { 170 char src[] = {1, 2, 3, 4}; 171 char dst[1]; 172 173 memmove(dst, src, 4); // expected-warning{{out-of-bound}} 174} 175 176//===----------------------------------------------------------------------=== 177// memcmp() 178//===----------------------------------------------------------------------=== 179 180#ifdef VARIANT 181 182#define bcmp BUILTIN(bcmp) 183// __builtin_bcmp is not defined with const in Builtins.def. 184int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 185#define memcmp bcmp 186 187#else /* VARIANT */ 188 189#define memcmp BUILTIN(memcmp) 190int memcmp(const void *s1, const void *s2, size_t n); 191 192#endif /* VARIANT */ 193 194 195void memcmp0 () { 196 char a[] = {1, 2, 3, 4}; 197 char b[4] = { 0 }; 198 199 memcmp(a, b, 4); // no-warning 200} 201 202void memcmp1 () { 203 char a[] = {1, 2, 3, 4}; 204 char b[10] = { 0 }; 205 206 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 207} 208 209void memcmp2 () { 210 char a[] = {1, 2, 3, 4}; 211 char b[1] = { 0 }; 212 213 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 214} 215 216void memcmp3 () { 217 char a[] = {1, 2, 3, 4}; 218 219 if (memcmp(a, a, 4)) 220 (void)*(char*)0; // no-warning 221} 222 223void memcmp4 (char *input) { 224 char a[] = {1, 2, 3, 4}; 225 226 if (memcmp(a, input, 4)) 227 (void)*(char*)0; // expected-warning{{null}} 228} 229 230void memcmp5 (char *input) { 231 char a[] = {1, 2, 3, 4}; 232 233 if (memcmp(a, 0, 0)) // no-warning 234 (void)*(char*)0; // no-warning 235 if (memcmp(0, a, 0)) // no-warning 236 (void)*(char*)0; // no-warning 237 if (memcmp(a, input, 0)) // no-warning 238 (void)*(char*)0; // no-warning 239} 240 241void memcmp6 (char *a, char *b, size_t n) { 242 int result = memcmp(a, b, n); 243 if (result != 0) 244 return; 245 if (n == 0) 246 (void)*(char*)0; // expected-warning{{null}} 247} 248 249//===----------------------------------------------------------------------=== 250// bcopy() 251//===----------------------------------------------------------------------=== 252 253#define bcopy BUILTIN(bcopy) 254// __builtin_bcopy is not defined with const in Builtins.def. 255void bcopy(/*const*/ void *s1, void *s2, size_t n); 256 257 258void bcopy0 () { 259 char src[] = {1, 2, 3, 4}; 260 char dst[4]; 261 262 bcopy(src, dst, 4); // no-warning 263} 264 265void bcopy1 () { 266 char src[] = {1, 2, 3, 4}; 267 char dst[10]; 268 269 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 270} 271 272void bcopy2 () { 273 char src[] = {1, 2, 3, 4}; 274 char dst[1]; 275 276 bcopy(src, dst, 4); // expected-warning{{out-of-bound}} 277} 278