1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s 4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -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 27 typedef typeof(sizeof(int)) size_t; 28 29 void clang_analyzer_eval(int); 30 31 //===----------------------------------------------------------------------=== 32 // memcpy() 33 //===----------------------------------------------------------------------=== 34 35 #ifdef VARIANT 36 37 #define __memcpy_chk BUILTIN(__memcpy_chk) 38 void *__memcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 39 size_t destlen); 40 41 #define memcpy(a,b,c) __memcpy_chk(a,b,c,(size_t)-1) 42 43 #else /* VARIANT */ 44 45 #define memcpy BUILTIN(memcpy) 46 void *memcpy(void *restrict s1, const void *restrict s2, size_t n); 47 48 #endif /* VARIANT */ 49 50 51 void memcpy0 () { 52 char src[] = {1, 2, 3, 4}; 53 char dst[4] = {0}; 54 55 memcpy(dst, src, 4); // no-warning 56 57 clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}} 58 59 // If we actually model the copy, we can make this known. 60 // The important thing for now is that the old value has been invalidated. 61 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 62 } 63 64 void memcpy1 () { 65 char src[] = {1, 2, 3, 4}; 66 char dst[10]; 67 68 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 69 } 70 71 void memcpy2 () { 72 char src[] = {1, 2, 3, 4}; 73 char dst[1]; 74 75 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 76 } 77 78 void memcpy3 () { 79 char src[] = {1, 2, 3, 4}; 80 char dst[3]; 81 82 memcpy(dst+1, src+2, 2); // no-warning 83 } 84 85 void memcpy4 () { 86 char src[] = {1, 2, 3, 4}; 87 char dst[10]; 88 89 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 90 } 91 92 void memcpy5() { 93 char src[] = {1, 2, 3, 4}; 94 char dst[3]; 95 96 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 97 } 98 99 void memcpy6() { 100 int a[4] = {0}; 101 memcpy(a, a, 8); // expected-warning{{overlapping}} 102 } 103 104 void memcpy7() { 105 int a[4] = {0}; 106 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 107 } 108 109 void memcpy8() { 110 int a[4] = {0}; 111 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 112 } 113 114 void memcpy9() { 115 int a[4] = {0}; 116 memcpy(a+2, a+1, 4); // no-warning 117 memcpy(a+1, a+2, 4); // no-warning 118 } 119 120 void memcpy10() { 121 char a[4] = {0}; 122 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 123 } 124 125 void memcpy11() { 126 char a[4] = {0}; 127 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 128 } 129 130 void memcpy12() { 131 char a[4] = {0}; 132 memcpy(0, a, 0); // no-warning 133 } 134 135 void memcpy13() { 136 char a[4] = {0}; 137 memcpy(a, 0, 0); // no-warning 138 } 139 140 void memcpy_unknown_size (size_t n) { 141 char a[4], b[4] = {1}; 142 clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}} 143 } 144 145 void memcpy_unknown_size_warn (size_t n) { 146 char a[4]; 147 void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 148 clang_analyzer_eval(result == a); // no-warning (above is fatal) 149 } 150 151 //===----------------------------------------------------------------------=== 152 // mempcpy() 153 //===----------------------------------------------------------------------=== 154 155 #ifdef VARIANT 156 157 #define __mempcpy_chk BUILTIN(__mempcpy_chk) 158 void *__mempcpy_chk(void *restrict s1, const void *restrict s2, size_t n, 159 size_t destlen); 160 161 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1) 162 163 #else /* VARIANT */ 164 165 #define mempcpy BUILTIN(mempcpy) 166 void *mempcpy(void *restrict s1, const void *restrict s2, size_t n); 167 168 #endif /* VARIANT */ 169 170 171 void mempcpy0 () { 172 char src[] = {1, 2, 3, 4}; 173 char dst[5] = {0}; 174 175 mempcpy(dst, src, 4); // no-warning 176 177 clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}} 178 179 // If we actually model the copy, we can make this known. 180 // The important thing for now is that the old value has been invalidated. 181 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 182 } 183 184 void mempcpy1 () { 185 char src[] = {1, 2, 3, 4}; 186 char dst[10]; 187 188 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 189 } 190 191 void mempcpy2 () { 192 char src[] = {1, 2, 3, 4}; 193 char dst[1]; 194 195 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 196 } 197 198 void mempcpy3 () { 199 char src[] = {1, 2, 3, 4}; 200 char dst[3]; 201 202 mempcpy(dst+1, src+2, 2); // no-warning 203 } 204 205 void mempcpy4 () { 206 char src[] = {1, 2, 3, 4}; 207 char dst[10]; 208 209 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 210 } 211 212 void mempcpy5() { 213 char src[] = {1, 2, 3, 4}; 214 char dst[3]; 215 216 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 217 } 218 219 void mempcpy6() { 220 int a[4] = {0}; 221 mempcpy(a, a, 8); // expected-warning{{overlapping}} 222 } 223 224 void mempcpy7() { 225 int a[4] = {0}; 226 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 227 } 228 229 void mempcpy8() { 230 int a[4] = {0}; 231 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 232 } 233 234 void mempcpy9() { 235 int a[4] = {0}; 236 mempcpy(a+2, a+1, 4); // no-warning 237 mempcpy(a+1, a+2, 4); // no-warning 238 } 239 240 void mempcpy10() { 241 char a[4] = {0}; 242 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 243 } 244 245 void mempcpy11() { 246 char a[4] = {0}; 247 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 248 } 249 250 void mempcpy12() { 251 char a[4] = {0}; 252 mempcpy(0, a, 0); // no-warning 253 } 254 255 void mempcpy13() { 256 char a[4] = {0}; 257 mempcpy(a, 0, 0); // no-warning 258 } 259 260 void mempcpy14() { 261 int src[] = {1, 2, 3, 4}; 262 int dst[5] = {0}; 263 int *p; 264 265 p = mempcpy(dst, src, 4 * sizeof(int)); 266 267 clang_analyzer_eval(p == &dst[4]); // expected-warning{{TRUE}} 268 } 269 270 struct st { 271 int i; 272 int j; 273 }; 274 275 void mempcpy15() { 276 struct st s1 = {0}; 277 struct st s2; 278 struct st *p1; 279 struct st *p2; 280 281 p1 = (&s2) + 1; 282 p2 = mempcpy(&s2, &s1, sizeof(struct st)); 283 284 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 285 } 286 287 void mempcpy16() { 288 struct st s1[10] = {{0}}; 289 struct st s2[10]; 290 struct st *p1; 291 struct st *p2; 292 293 p1 = (&s2[0]) + 5; 294 p2 = mempcpy(&s2[0], &s1[0], 5 * sizeof(struct st)); 295 296 clang_analyzer_eval(p1 == p2); // expected-warning{{TRUE}} 297 } 298 299 void mempcpy_unknown_size_warn (size_t n) { 300 char a[4]; 301 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 302 clang_analyzer_eval(result == a); // no-warning (above is fatal) 303 } 304 305 void mempcpy_unknownable_size (char *src, float n) { 306 char a[4]; 307 // This used to crash because we don't model floats. 308 mempcpy(a, src, (size_t)n); 309 } 310 311 //===----------------------------------------------------------------------=== 312 // memmove() 313 //===----------------------------------------------------------------------=== 314 315 #ifdef VARIANT 316 317 #define __memmove_chk BUILTIN(__memmove_chk) 318 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 319 320 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 321 322 #else /* VARIANT */ 323 324 #define memmove BUILTIN(memmove) 325 void *memmove(void *s1, const void *s2, size_t n); 326 327 #endif /* VARIANT */ 328 329 330 void memmove0 () { 331 char src[] = {1, 2, 3, 4}; 332 char dst[4] = {0}; 333 334 memmove(dst, src, 4); // no-warning 335 336 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}} 337 338 // If we actually model the copy, we can make this known. 339 // The important thing for now is that the old value has been invalidated. 340 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 341 } 342 343 void memmove1 () { 344 char src[] = {1, 2, 3, 4}; 345 char dst[10]; 346 347 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 348 } 349 350 void memmove2 () { 351 char src[] = {1, 2, 3, 4}; 352 char dst[1]; 353 354 memmove(dst, src, 4); // expected-warning{{overflow}} 355 } 356 357 //===----------------------------------------------------------------------=== 358 // memcmp() 359 //===----------------------------------------------------------------------=== 360 361 #ifdef VARIANT 362 363 #define bcmp BUILTIN(bcmp) 364 // __builtin_bcmp is not defined with const in Builtins.def. 365 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 366 #define memcmp bcmp 367 // 368 #else /* VARIANT */ 369 370 #define memcmp BUILTIN(memcmp) 371 int memcmp(const void *s1, const void *s2, size_t n); 372 373 #endif /* VARIANT */ 374 375 376 void memcmp0 () { 377 char a[] = {1, 2, 3, 4}; 378 char b[4] = { 0 }; 379 380 memcmp(a, b, 4); // no-warning 381 } 382 383 void memcmp1 () { 384 char a[] = {1, 2, 3, 4}; 385 char b[10] = { 0 }; 386 387 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 388 } 389 390 void memcmp2 () { 391 char a[] = {1, 2, 3, 4}; 392 char b[1] = { 0 }; 393 394 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 395 } 396 397 void memcmp3 () { 398 char a[] = {1, 2, 3, 4}; 399 400 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}} 401 } 402 403 void memcmp4 (char *input) { 404 char a[] = {1, 2, 3, 4}; 405 406 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}} 407 } 408 409 void memcmp5 (char *input) { 410 char a[] = {1, 2, 3, 4}; 411 412 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}} 413 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}} 414 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}} 415 } 416 417 void memcmp6 (char *a, char *b, size_t n) { 418 int result = memcmp(a, b, n); 419 if (result != 0) 420 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}} 421 // else 422 // analyzer_assert_unknown(n == 0); 423 424 // We can't do the above comparison because n has already been constrained. 425 // On one path n == 0, on the other n != 0. 426 } 427 428 int memcmp7 (char *a, size_t x, size_t y, size_t n) { 429 // We used to crash when either of the arguments was unknown. 430 return memcmp(a, &a[x*y], n) + 431 memcmp(&a[x*y], a, n); 432 } 433 434 //===----------------------------------------------------------------------=== 435 // bcopy() 436 //===----------------------------------------------------------------------=== 437 438 #define bcopy BUILTIN(bcopy) 439 // __builtin_bcopy is not defined with const in Builtins.def. 440 void bcopy(/*const*/ void *s1, void *s2, size_t n); 441 442 443 void bcopy0 () { 444 char src[] = {1, 2, 3, 4}; 445 char dst[4] = {0}; 446 447 bcopy(src, dst, 4); // no-warning 448 449 // If we actually model the copy, we can make this known. 450 // The important thing for now is that the old value has been invalidated. 451 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 452 } 453 454 void bcopy1 () { 455 char src[] = {1, 2, 3, 4}; 456 char dst[10]; 457 458 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 459 } 460 461 void bcopy2 () { 462 char src[] = {1, 2, 3, 4}; 463 char dst[1]; 464 465 bcopy(src, dst, 4); // expected-warning{{overflow}} 466 } 467 468 void *malloc(size_t); 469 void free(void *); 470 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { 471 char *bytes = malloc(sizeof(char) * (length + 1)); 472 memcpy(bytes, input, length); 473 char x = bytes[0]; // no warning 474 free(bytes); 475 return x; 476 } 477