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 mempcpy_unknown_size_warn (size_t n) { 261 char a[4]; 262 void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}} 263 clang_analyzer_eval(result == a); // no-warning (above is fatal) 264 } 265 266 void mempcpy_unknownable_size (char *src, float n) { 267 char a[4]; 268 // This used to crash because we don't model floats. 269 mempcpy(a, src, (size_t)n); 270 } 271 272 //===----------------------------------------------------------------------=== 273 // memmove() 274 //===----------------------------------------------------------------------=== 275 276 #ifdef VARIANT 277 278 #define __memmove_chk BUILTIN(__memmove_chk) 279 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 280 281 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 282 283 #else /* VARIANT */ 284 285 #define memmove BUILTIN(memmove) 286 void *memmove(void *s1, const void *s2, size_t n); 287 288 #endif /* VARIANT */ 289 290 291 void memmove0 () { 292 char src[] = {1, 2, 3, 4}; 293 char dst[4] = {0}; 294 295 memmove(dst, src, 4); // no-warning 296 297 clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}} 298 299 // If we actually model the copy, we can make this known. 300 // The important thing for now is that the old value has been invalidated. 301 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 302 } 303 304 void memmove1 () { 305 char src[] = {1, 2, 3, 4}; 306 char dst[10]; 307 308 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 309 } 310 311 void memmove2 () { 312 char src[] = {1, 2, 3, 4}; 313 char dst[1]; 314 315 memmove(dst, src, 4); // expected-warning{{overflow}} 316 } 317 318 //===----------------------------------------------------------------------=== 319 // memcmp() 320 //===----------------------------------------------------------------------=== 321 322 #ifdef VARIANT 323 324 #define bcmp BUILTIN(bcmp) 325 // __builtin_bcmp is not defined with const in Builtins.def. 326 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 327 #define memcmp bcmp 328 // 329 #else /* VARIANT */ 330 331 #define memcmp BUILTIN(memcmp) 332 int memcmp(const void *s1, const void *s2, size_t n); 333 334 #endif /* VARIANT */ 335 336 337 void memcmp0 () { 338 char a[] = {1, 2, 3, 4}; 339 char b[4] = { 0 }; 340 341 memcmp(a, b, 4); // no-warning 342 } 343 344 void memcmp1 () { 345 char a[] = {1, 2, 3, 4}; 346 char b[10] = { 0 }; 347 348 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 349 } 350 351 void memcmp2 () { 352 char a[] = {1, 2, 3, 4}; 353 char b[1] = { 0 }; 354 355 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 356 } 357 358 void memcmp3 () { 359 char a[] = {1, 2, 3, 4}; 360 361 clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}} 362 } 363 364 void memcmp4 (char *input) { 365 char a[] = {1, 2, 3, 4}; 366 367 clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}} 368 } 369 370 void memcmp5 (char *input) { 371 char a[] = {1, 2, 3, 4}; 372 373 clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}} 374 clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}} 375 clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}} 376 } 377 378 void memcmp6 (char *a, char *b, size_t n) { 379 int result = memcmp(a, b, n); 380 if (result != 0) 381 clang_analyzer_eval(n != 0); // expected-warning{{TRUE}} 382 // else 383 // analyzer_assert_unknown(n == 0); 384 385 // We can't do the above comparison because n has already been constrained. 386 // On one path n == 0, on the other n != 0. 387 } 388 389 int memcmp7 (char *a, size_t x, size_t y, size_t n) { 390 // We used to crash when either of the arguments was unknown. 391 return memcmp(a, &a[x*y], n) + 392 memcmp(&a[x*y], a, n); 393 } 394 395 //===----------------------------------------------------------------------=== 396 // bcopy() 397 //===----------------------------------------------------------------------=== 398 399 #define bcopy BUILTIN(bcopy) 400 // __builtin_bcopy is not defined with const in Builtins.def. 401 void bcopy(/*const*/ void *s1, void *s2, size_t n); 402 403 404 void bcopy0 () { 405 char src[] = {1, 2, 3, 4}; 406 char dst[4] = {0}; 407 408 bcopy(src, dst, 4); // no-warning 409 410 // If we actually model the copy, we can make this known. 411 // The important thing for now is that the old value has been invalidated. 412 clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}} 413 } 414 415 void bcopy1 () { 416 char src[] = {1, 2, 3, 4}; 417 char dst[10]; 418 419 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 420 } 421 422 void bcopy2 () { 423 char src[] = {1, 2, 3, 4}; 424 char dst[1]; 425 426 bcopy(src, dst, 4); // expected-warning{{overflow}} 427 } 428 429 void *malloc(size_t); 430 void free(void *); 431 char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { 432 char *bytes = malloc(sizeof(char) * (length + 1)); 433 memcpy(bytes, input, length); 434 char x = bytes[0]; // no warning 435 free(bytes); 436 return x; 437 } 438