1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s 2 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s 3 // RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s 4 // RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring.NullArg,experimental.unix.cstring.OutOfBounds,experimental.unix.cstring.BufferOverlap,experimental.unix.cstring.NotNullTerminated -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 27 typedef typeof(sizeof(int)) size_t; 28 29 //===----------------------------------------------------------------------=== 30 // memcpy() 31 //===----------------------------------------------------------------------=== 32 33 #ifdef VARIANT 34 35 #define __memcpy_chk BUILTIN(__memcpy_chk) 36 void *__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) 44 void *memcpy(void *restrict s1, const void *restrict s2, size_t n); 45 46 #endif /* VARIANT */ 47 48 49 void 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 63 void memcpy1 () { 64 char src[] = {1, 2, 3, 4}; 65 char dst[10]; 66 67 memcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 68 } 69 70 void memcpy2 () { 71 char src[] = {1, 2, 3, 4}; 72 char dst[1]; 73 74 memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 75 } 76 77 void memcpy3 () { 78 char src[] = {1, 2, 3, 4}; 79 char dst[3]; 80 81 memcpy(dst+1, src+2, 2); // no-warning 82 } 83 84 void memcpy4 () { 85 char src[] = {1, 2, 3, 4}; 86 char dst[10]; 87 88 memcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 89 } 90 91 void memcpy5() { 92 char src[] = {1, 2, 3, 4}; 93 char dst[3]; 94 95 memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 96 } 97 98 void memcpy6() { 99 int a[4] = {0}; 100 memcpy(a, a, 8); // expected-warning{{overlapping}} 101 } 102 103 void memcpy7() { 104 int a[4] = {0}; 105 memcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 106 } 107 108 void memcpy8() { 109 int a[4] = {0}; 110 memcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 111 } 112 113 void 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 119 void memcpy10() { 120 char a[4] = {0}; 121 memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 122 } 123 124 void memcpy11() { 125 char a[4] = {0}; 126 memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 127 } 128 129 void memcpy12() { 130 char a[4] = {0}; 131 memcpy(0, a, 0); // no-warning 132 } 133 134 void memcpy13() { 135 char a[4] = {0}; 136 memcpy(a, 0, 0); // no-warning 137 } 138 139 void memcpy_unknown_size (size_t n) { 140 char a[4], b[4] = {1}; 141 if (memcpy(a, b, n) != a) 142 (void)*(char*)0; // no-warning 143 } 144 145 void memcpy_unknown_size_warn (size_t n) { 146 char a[4]; 147 if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}} 148 (void)*(char*)0; // no-warning 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 if (mempcpy(dst, src, 4) != &dst[4]) { 178 (void)*(char*)0; // no-warning 179 } 180 181 if (dst[0] != 0) 182 (void)*(char*)0; // expected-warning{{null}} 183 } 184 185 void mempcpy1 () { 186 char src[] = {1, 2, 3, 4}; 187 char dst[10]; 188 189 mempcpy(dst, src, 5); // expected-warning{{Memory copy function accesses out-of-bound array element}} 190 } 191 192 void mempcpy2 () { 193 char src[] = {1, 2, 3, 4}; 194 char dst[1]; 195 196 mempcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}} 197 } 198 199 void mempcpy3 () { 200 char src[] = {1, 2, 3, 4}; 201 char dst[3]; 202 203 mempcpy(dst+1, src+2, 2); // no-warning 204 } 205 206 void mempcpy4 () { 207 char src[] = {1, 2, 3, 4}; 208 char dst[10]; 209 210 mempcpy(dst+2, src+2, 3); // expected-warning{{Memory copy function accesses out-of-bound array element}} 211 } 212 213 void mempcpy5() { 214 char src[] = {1, 2, 3, 4}; 215 char dst[3]; 216 217 mempcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}} 218 } 219 220 void mempcpy6() { 221 int a[4] = {0}; 222 mempcpy(a, a, 8); // expected-warning{{overlapping}} 223 } 224 225 void mempcpy7() { 226 int a[4] = {0}; 227 mempcpy(a+2, a+1, 8); // expected-warning{{overlapping}} 228 } 229 230 void mempcpy8() { 231 int a[4] = {0}; 232 mempcpy(a+1, a+2, 8); // expected-warning{{overlapping}} 233 } 234 235 void mempcpy9() { 236 int a[4] = {0}; 237 mempcpy(a+2, a+1, 4); // no-warning 238 mempcpy(a+1, a+2, 4); // no-warning 239 } 240 241 void mempcpy10() { 242 char a[4] = {0}; 243 mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 244 } 245 246 void mempcpy11() { 247 char a[4] = {0}; 248 mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}} 249 } 250 251 void mempcpy12() { 252 char a[4] = {0}; 253 mempcpy(0, a, 0); // no-warning 254 } 255 256 void mempcpy13() { 257 char a[4] = {0}; 258 mempcpy(a, 0, 0); // no-warning 259 } 260 261 void mempcpy_unknown_size_warn (size_t n) { 262 char a[4]; 263 if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}} 264 (void)*(char*)0; // no-warning 265 } 266 267 void mempcpy_unknownable_size (char *src, float n) { 268 char a[4]; 269 // This used to crash because we don't model floats. 270 mempcpy(a, src, (size_t)n); 271 } 272 273 //===----------------------------------------------------------------------=== 274 // memmove() 275 //===----------------------------------------------------------------------=== 276 277 #ifdef VARIANT 278 279 #define __memmove_chk BUILTIN(__memmove_chk) 280 void *__memmove_chk(void *s1, const void *s2, size_t n, size_t destlen); 281 282 #define memmove(a,b,c) __memmove_chk(a,b,c,(size_t)-1) 283 284 #else /* VARIANT */ 285 286 #define memmove BUILTIN(memmove) 287 void *memmove(void *s1, const void *s2, size_t n); 288 289 #endif /* VARIANT */ 290 291 292 void memmove0 () { 293 char src[] = {1, 2, 3, 4}; 294 char dst[4] = {0}; 295 296 memmove(dst, src, 4); // no-warning 297 298 if (memmove(dst, src, 4) != dst) { 299 (void)*(char*)0; // no-warning 300 } 301 302 if (dst[0] != 0) 303 (void)*(char*)0; // expected-warning{{null}} 304 } 305 306 void memmove1 () { 307 char src[] = {1, 2, 3, 4}; 308 char dst[10]; 309 310 memmove(dst, src, 5); // expected-warning{{out-of-bound}} 311 } 312 313 void memmove2 () { 314 char src[] = {1, 2, 3, 4}; 315 char dst[1]; 316 317 memmove(dst, src, 4); // expected-warning{{overflow}} 318 } 319 320 //===----------------------------------------------------------------------=== 321 // memcmp() 322 //===----------------------------------------------------------------------=== 323 324 #ifdef VARIANT 325 326 #define bcmp BUILTIN(bcmp) 327 // __builtin_bcmp is not defined with const in Builtins.def. 328 int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n); 329 #define memcmp bcmp 330 331 #else /* VARIANT */ 332 333 #define memcmp BUILTIN(memcmp) 334 int memcmp(const void *s1, const void *s2, size_t n); 335 336 #endif /* VARIANT */ 337 338 339 void memcmp0 () { 340 char a[] = {1, 2, 3, 4}; 341 char b[4] = { 0 }; 342 343 memcmp(a, b, 4); // no-warning 344 } 345 346 void memcmp1 () { 347 char a[] = {1, 2, 3, 4}; 348 char b[10] = { 0 }; 349 350 memcmp(a, b, 5); // expected-warning{{out-of-bound}} 351 } 352 353 void memcmp2 () { 354 char a[] = {1, 2, 3, 4}; 355 char b[1] = { 0 }; 356 357 memcmp(a, b, 4); // expected-warning{{out-of-bound}} 358 } 359 360 void memcmp3 () { 361 char a[] = {1, 2, 3, 4}; 362 363 if (memcmp(a, a, 4)) 364 (void)*(char*)0; // no-warning 365 } 366 367 void memcmp4 (char *input) { 368 char a[] = {1, 2, 3, 4}; 369 370 if (memcmp(a, input, 4)) 371 (void)*(char*)0; // expected-warning{{null}} 372 } 373 374 void memcmp5 (char *input) { 375 char a[] = {1, 2, 3, 4}; 376 377 if (memcmp(a, 0, 0)) // no-warning 378 (void)*(char*)0; // no-warning 379 if (memcmp(0, a, 0)) // no-warning 380 (void)*(char*)0; // no-warning 381 if (memcmp(a, input, 0)) // no-warning 382 (void)*(char*)0; // no-warning 383 } 384 385 void memcmp6 (char *a, char *b, size_t n) { 386 int result = memcmp(a, b, n); 387 if (result != 0) 388 return; 389 if (n == 0) 390 (void)*(char*)0; // expected-warning{{null}} 391 } 392 393 int memcmp7 (char *a, size_t x, size_t y, size_t n) { 394 // We used to crash when either of the arguments was unknown. 395 return memcmp(a, &a[x*y], n) + 396 memcmp(&a[x*y], a, n); 397 } 398 399 //===----------------------------------------------------------------------=== 400 // bcopy() 401 //===----------------------------------------------------------------------=== 402 403 #define bcopy BUILTIN(bcopy) 404 // __builtin_bcopy is not defined with const in Builtins.def. 405 void bcopy(/*const*/ void *s1, void *s2, size_t n); 406 407 408 void bcopy0 () { 409 char src[] = {1, 2, 3, 4}; 410 char dst[4] = {0}; 411 412 bcopy(src, dst, 4); // no-warning 413 414 if (dst[0] != 0) 415 (void)*(char*)0; // expected-warning{{null}} 416 } 417 418 void bcopy1 () { 419 char src[] = {1, 2, 3, 4}; 420 char dst[10]; 421 422 bcopy(src, dst, 5); // expected-warning{{out-of-bound}} 423 } 424 425 void bcopy2 () { 426 char src[] = {1, 2, 3, 4}; 427 char dst[1]; 428 429 bcopy(src, dst, 4); // expected-warning{{overflow}} 430 } 431