bstring.c revision 8a285ae6fc4926cc4e419025eec63e2d6696e13f
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s 2// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s 3// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -verify %s 4// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,cplusplus.experimental.CString -analyzer-store=region -Wno-null-dereference -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 available 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] = {0}; 52 53 memcpy(dst, src, 4); // no-warning 54 55 if (memcpy(dst, src, 4) != dst) { 56 (void)*(char*)0; // no-warning 57 } 58 59 if (dst[0] != 0) 60 (void)*(char*)0; // expected-warning{{null}} 61} 62 63void memcpy1 () { 64 char src[] = {1, 2, 3, 4}; 65 char dst[10]; 66 67 memcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}} 68} 69 70void memcpy2 () { 71 char src[] = {1, 2, 3, 4}; 72 char dst[1]; 73 74 memcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}} 75} 76 77void memcpy3 () { 78 char src[] = {1, 2, 3, 4}; 79 char dst[3]; 80 81 memcpy(dst+1, src+2, 2); // no-warning 82} 83 84void memcpy4 () { 85 char src[] = {1, 2, 3, 4}; 86 char dst[10]; 87 88 memcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}} 89} 90 91void memcpy5() { 92 char src[] = {1, 2, 3, 4}; 93 char dst[3]; 94 95 memcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}} 96} 97 98void memcpy6() { 99 int a[4] = {0}; 100 memcpy(a, a, 8); // expected-warning{{overlapping}} 101} 102 103void memcpy7() { 104 int a[4] = {0}; 105 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 106} 107 108void memcpy8() { 109 int a[4] = {0}; 110 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 111} 112 113void memcpy9() { 114 int a[4] = {0}; 115 memcpy(a+2, a+1, 4); // no-warning 116 memcpy(a+1, a+2, 4); // no-warning 117} 118 119void memcpy10() { 120 char a[4] = {0}; 121 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} 122} 123 124void memcpy11() { 125 char a[4] = {0}; 126 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} 127} 128 129void memcpy12() { 130 char a[4] = {0}; 131 memcpy(0, a, 0); // no-warning 132} 133 134void memcpy13() { 135 char a[4] = {0}; 136 memcpy(a, 0, 0); // no-warning 137} 138 139//===----------------------------------------------------------------------=== 140// mempcpy() 141//===----------------------------------------------------------------------=== 142 143#define mempcpy BUILTIN(mempcpy) 144void *mempcpy(void *restrict s1, const void *restrict s2, size_t n); 145 146void mempcpy0 () { 147 char src[] = {1, 2, 3, 4}; 148 char dst[5] = {0}; 149 150 mempcpy(dst, src, 4); // no-warning 151 152 if (mempcpy(dst, src, 4) != &dst[4]) { 153 (void)*(char*)0; // no-warning 154 } 155 156 if (dst[0] != 0) 157 (void)*(char*)0; // expected-warning{{null}} 158} 159 160void mempcpy1 () { 161 char src[] = {1, 2, 3, 4}; 162 char dst[10]; 163 164 mempcpy(dst, src, 5); // expected-warning{{Byte string function accesses out-of-bound array element}} 165} 166 167void mempcpy2 () { 168 char src[] = {1, 2, 3, 4}; 169 char dst[1]; 170 171 mempcpy(dst, src, 4); // expected-warning{{Byte string function overflows destination buffer}} 172} 173 174void mempcpy3 () { 175 char src[] = {1, 2, 3, 4}; 176 char dst[3]; 177 178 mempcpy(dst+1, src+2, 2); // no-warning 179} 180 181void mempcpy4 () { 182 char src[] = {1, 2, 3, 4}; 183 char dst[10]; 184 185 mempcpy(dst+2, src+2, 3); // expected-warning{{Byte string function accesses out-of-bound array element}} 186} 187 188void mempcpy5() { 189 char src[] = {1, 2, 3, 4}; 190 char dst[3]; 191 192 mempcpy(dst+2, src+2, 2); // expected-warning{{Byte string function overflows destination buffer}} 193} 194 195void mempcpy6() { 196 int a[4] = {0}; 197 mempcpy(a, a, 8); // expected-warning{{overlapping}} 198} 199 200void mempcpy7() { 201 int a[4] = {0}; 202 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 203} 204 205void mempcpy8() { 206 int a[4] = {0}; 207 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 208} 209 210void mempcpy9() { 211 int a[4] = {0}; 212 mempcpy(a+2, a+1, 4); // no-warning 213 mempcpy(a+1, a+2, 4); // no-warning 214} 215 216void mempcpy10() { 217 char a[4] = {0}; 218 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to byte string function}} 219} 220 221void mempcpy11() { 222 char a[4] = {0}; 223 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to byte string function}} 224} 225 226void mempcpy12() { 227 char a[4] = {0}; 228 mempcpy(0, a, 0); // no-warning 229} 230 231void mempcpy13() { 232 char a[4] = {0}; 233 mempcpy(a, 0, 0); // no-warning 234} 235 236//===----------------------------------------------------------------------=== 237// memmove() 238//===----------------------------------------------------------------------=== 239 240#ifdef VARIANT 241 242#define __memmove_chk BUILTIN(__memmove_chk) 243void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 244 245#define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 246 247#else /* VARIANT */ 248 249#define memmove BUILTIN(memmove) 250void *memmove(void *s1, const void *s2, size_t n); 251 252#endif /* VARIANT */ 253 254 255void memmove0 () { 256 char src[] = {1, 2, 3, 4}; 257 char dst[4] = {0}; 258 259 memmove(dst, src, 4); // no-warning 260 261 if (memmove(dst, src, 4) != dst) { 262 (void)*(char*)0; // no-warning 263 } 264 265 if (dst[0] != 0) 266 (void)*(char*)0; // expected-warning{{null}} 267} 268 269void memmove1 () { 270 char src[] = {1, 2, 3, 4}; 271 char dst[10]; 272 273 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 274} 275 276void memmove2 () { 277 char src[] = {1, 2, 3, 4}; 278 char dst[1]; 279 280 memmove(dst, src, 4); // expected-warning{{overflow}} 281} 282 283//===----------------------------------------------------------------------=== 284// memcmp() 285//===----------------------------------------------------------------------=== 286 287#ifdef VARIANT 288 289#define bcmp BUILTIN(bcmp) 290// __builtin_bcmp is not defined with const in Builtins.def. 291int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 292#define memcmp bcmp 293 294#else /* VARIANT */ 295 296#define memcmp BUILTIN(memcmp) 297int memcmp(const void *s1, const void *s2, size_t n); 298 299#endif /* VARIANT */ 300 301 302void memcmp0 () { 303 char a[] = {1, 2, 3, 4}; 304 char b[4] = { 0 }; 305 306 memcmp(a, b, 4); // no-warning 307} 308 309void memcmp1 () { 310 char a[] = {1, 2, 3, 4}; 311 char b[10] = { 0 }; 312 313 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 314} 315 316void memcmp2 () { 317 char a[] = {1, 2, 3, 4}; 318 char b[1] = { 0 }; 319 320 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 321} 322 323void memcmp3 () { 324 char a[] = {1, 2, 3, 4}; 325 326 if (memcmp(a, a, 4)) 327 (void)*(char*)0; // no-warning 328} 329 330void memcmp4 (char *input) { 331 char a[] = {1, 2, 3, 4}; 332 333 if (memcmp(a, input, 4)) 334 (void)*(char*)0; // expected-warning{{null}} 335} 336 337void memcmp5 (char *input) { 338 char a[] = {1, 2, 3, 4}; 339 340 if (memcmp(a, 0, 0)) // no-warning 341 (void)*(char*)0; // no-warning 342 if (memcmp(0, a, 0)) // no-warning 343 (void)*(char*)0; // no-warning 344 if (memcmp(a, input, 0)) // no-warning 345 (void)*(char*)0; // no-warning 346} 347 348void memcmp6 (char *a, char *b, size_t n) { 349 int result = memcmp(a, b, n); 350 if (result != 0) 351 return; 352 if (n == 0) 353 (void)*(char*)0; // expected-warning{{null}} 354} 355 356int memcmp7 (char *a, size_t x, size_t y, size_t n) { 357 // We used to crash when either of the arguments was unknown. 358 return memcmp(a, &a[x*y], n) + 359 memcmp(&a[x*y], a, n); 360} 361 362//===----------------------------------------------------------------------=== 363// bcopy() 364//===----------------------------------------------------------------------=== 365 366#define bcopy BUILTIN(bcopy) 367// __builtin_bcopy is not defined with const in Builtins.def. 368void bcopy(/*const*/ void *s1, void *s2, size_t n); 369 370 371void bcopy0 () { 372 char src[] = {1, 2, 3, 4}; 373 char dst[4] = {0}; 374 375 bcopy(src, dst, 4); // no-warning 376 377 if (dst[0] != 0) 378 (void)*(char*)0; // expected-warning{{null}} 379} 380 381void bcopy1 () { 382 char src[] = {1, 2, 3, 4}; 383 char dst[10]; 384 385 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 386} 387 388void bcopy2 () { 389 char src[] = {1, 2, 3, 4}; 390 char dst[1]; 391 392 bcopy(src, dst, 4); // expected-warning{{overflow}} 393} 394