1 // Given code 'struct aa { char s1[4]; char * s2;} a; memcpy(a.s1, ...);', 2 // this test checks that the CStringChecker only invalidates the destination buffer array a.s1 (instead of a.s1 and a.s2). 3 // At the moment the whole of the destination array content is invalidated. 4 // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated. 5 // Specific triple set to test structures of size 0. 6 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s 7 8 typedef __typeof(sizeof(int)) size_t; 9 10 char *strdup(const char *s); 11 void free(void *); 12 void *memcpy(void *dst, const void *src, size_t n); // expected-note{{passing argument to parameter 'dst' here}} 13 void *malloc(size_t n); 14 15 void clang_analyzer_eval(int); 16 17 struct aa { 18 char s1[4]; 19 char *s2; 20 }; 21 22 // Test different types of structure initialisation. 23 int f0() { 24 struct aa a0 = {{1, 2, 3, 4}, 0}; 25 a0.s2 = strdup("hello"); 26 char input[] = {'a', 'b', 'c', 'd'}; 27 memcpy(a0.s1, input, 4); 28 clang_analyzer_eval(a0.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 29 clang_analyzer_eval(a0.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 30 clang_analyzer_eval(a0.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 31 clang_analyzer_eval(a0.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 32 clang_analyzer_eval(a0.s2 == 0); // expected-warning{{UNKNOWN}} 33 free(a0.s2); // no warning 34 return 0; 35 } 36 37 int f1() { 38 struct aa a1; 39 a1.s2 = strdup("hello"); 40 char input[] = {'a', 'b', 'c', 'd'}; 41 memcpy(a1.s1, input, 4); 42 clang_analyzer_eval(a1.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 43 clang_analyzer_eval(a1.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 44 clang_analyzer_eval(a1.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 45 clang_analyzer_eval(a1.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 46 clang_analyzer_eval(a1.s2 == 0); // expected-warning{{UNKNOWN}} 47 free(a1.s2); // no warning 48 return 0; 49 } 50 51 int f2() { 52 struct aa a2 = {{1, 2}}; 53 a2.s2 = strdup("hello"); 54 char input[] = {'a', 'b', 'c', 'd'}; 55 memcpy(a2.s1, input, 4); 56 clang_analyzer_eval(a2.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 57 clang_analyzer_eval(a2.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 58 clang_analyzer_eval(a2.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 59 clang_analyzer_eval(a2.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 60 clang_analyzer_eval(a2.s2 == 0); // expected-warning{{UNKNOWN}} 61 free(a2.s2); // no warning 62 return 0; 63 } 64 65 int f3() { 66 struct aa a3 = {{1, 2, 3, 4}, 0}; 67 a3.s2 = strdup("hello"); 68 char input[] = {'a', 'b', 'c', 'd'}; 69 int * dest = (int*)a3.s1; 70 memcpy(dest, input, 4); 71 clang_analyzer_eval(a3.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 72 clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}} 73 clang_analyzer_eval(a3.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 74 clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}} 75 clang_analyzer_eval(a3.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 76 clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}} 77 clang_analyzer_eval(a3.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 78 clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}} 79 clang_analyzer_eval(a3.s2 == 0); // expected-warning{{UNKNOWN}} 80 free(a3.s2); // no warning 81 return 0; 82 } 83 84 struct bb { 85 struct aa a; 86 char * s2; 87 }; 88 89 int f4() { 90 struct bb b0 = {{1, 2, 3, 4}, 0}; 91 b0.s2 = strdup("hello"); 92 b0.a.s2 = strdup("hola"); 93 char input[] = {'a', 'b', 'c', 'd'}; 94 char * dest = (char*)(b0.a.s1); 95 memcpy(dest, input, 4); 96 clang_analyzer_eval(b0.a.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 97 clang_analyzer_eval(dest[0] == 'a'); // expected-warning{{UNKNOWN}} 98 clang_analyzer_eval(b0.a.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 99 clang_analyzer_eval(dest[1] == 'b'); // expected-warning{{UNKNOWN}} 100 clang_analyzer_eval(b0.a.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 101 clang_analyzer_eval(dest[2] == 'c'); // expected-warning{{UNKNOWN}} 102 clang_analyzer_eval(b0.a.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 103 clang_analyzer_eval(dest[3] == 'd'); // expected-warning{{UNKNOWN}} 104 clang_analyzer_eval(b0.s2 == 0); // expected-warning{{UNKNOWN}} 105 free(b0.a.s2); // no warning 106 free(b0.s2); // no warning 107 return 0; 108 } 109 110 // Test that memory leaks are caught. 111 int f5() { 112 struct aa a0 = {{1, 2, 3, 4}, 0}; 113 a0.s2 = strdup("hello"); 114 char input[] = {'a', 'b', 'c', 'd'}; 115 memcpy(a0.s1, input, 4); 116 return 0; // expected-warning{{Potential leak of memory pointed to by 'a0.s2'}} 117 } 118 119 int f6() { 120 struct aa a1; 121 a1.s2 = strdup("hello"); 122 char input[] = {'a', 'b', 'c', 'd'}; 123 memcpy(a1.s1, input, 4); 124 return 0; // expected-warning{{Potential leak of memory pointed to by 'a1.s2'}} 125 } 126 127 int f7() { 128 struct aa a2 = {{1, 2}}; 129 a2.s2 = strdup("hello"); 130 char input[] = {'a', 'b', 'c', 'd'}; 131 memcpy(a2.s1, input, 4); 132 return 0; // expected-warning{{Potential leak of memory pointed to by 'a2.s2'}} 133 } 134 135 int f8() { 136 struct aa a3 = {{1, 2, 3, 4}, 0}; 137 a3.s2 = strdup("hello"); 138 char input[] = {'a', 'b', 'c', 'd'}; 139 int * dest = (int*)a3.s1; 140 memcpy(dest, input, 4); 141 return 0; // expected-warning{{Potential leak of memory pointed to by 'a3.s2'}} 142 } 143 144 int f9() { 145 struct bb b0 = {{1, 2, 3, 4}, 0}; 146 b0.s2 = strdup("hello"); 147 b0.a.s2 = strdup("hola"); 148 char input[] = {'a', 'b', 'c', 'd'}; 149 char * dest = (char*)(b0.a.s1); 150 memcpy(dest, input, 4); 151 free(b0.a.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.s2'}} 152 return 0; 153 } 154 155 int f10() { 156 struct bb b0 = {{1, 2, 3, 4}, 0}; 157 b0.s2 = strdup("hello"); 158 b0.a.s2 = strdup("hola"); 159 char input[] = {'a', 'b', 'c', 'd'}; 160 char * dest = (char*)(b0.a.s1); 161 memcpy(dest, input, 4); 162 free(b0.s2); // expected-warning{{Potential leak of memory pointed to by 'b0.a.s2'}} 163 return 0; 164 } 165 166 // Test invalidating fields being addresses of array. 167 struct cc { 168 char * s1; 169 char * s2; 170 }; 171 172 int f11() { 173 char x[4] = {1, 2}; 174 x[0] = 1; 175 x[1] = 2; 176 struct cc c0; 177 c0.s2 = strdup("hello"); 178 c0.s1 = &x[0]; 179 char input[] = {'a', 'b', 'c', 'd'}; 180 memcpy(c0.s1, input, 4); 181 clang_analyzer_eval(x[0] == 1); // expected-warning{{UNKNOWN}} 182 clang_analyzer_eval(x[1] == 2); // expected-warning{{UNKNOWN}} 183 clang_analyzer_eval(c0.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 184 clang_analyzer_eval(c0.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 185 clang_analyzer_eval(c0.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 186 clang_analyzer_eval(c0.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 187 free(c0.s2); // no-warning 188 return 0; 189 } 190 191 // Test inverting field position between s1 and s2. 192 struct dd { 193 char *s2; 194 char s1[4]; 195 }; 196 197 int f12() { 198 struct dd d0 = {0, {1, 2, 3, 4}}; 199 d0.s2 = strdup("hello"); 200 char input[] = {'a', 'b', 'c', 'd'}; 201 memcpy(d0.s1, input, 4); 202 clang_analyzer_eval(d0.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 203 clang_analyzer_eval(d0.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 204 clang_analyzer_eval(d0.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 205 clang_analyzer_eval(d0.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 206 clang_analyzer_eval(d0.s2 == 0); // expected-warning{{UNKNOWN}} 207 free(d0.s2); // no warning 208 return 0; 209 } 210 211 // Test arrays of structs. 212 struct ee { 213 int a; 214 char b; 215 }; 216 217 struct EE { 218 struct ee s1[2]; 219 char * s2; 220 }; 221 222 int f13() { 223 struct EE E0 = {{{1, 2}, {3, 4}}, 0}; 224 E0.s2 = strdup("hello"); 225 char input[] = {'a', 'b', 'c', 'd'}; 226 memcpy(E0.s1, input, 4); 227 clang_analyzer_eval(E0.s1[0].a == 'a'); // expected-warning{{UNKNOWN}} 228 clang_analyzer_eval(E0.s1[0].b == 'b'); // expected-warning{{UNKNOWN}} 229 clang_analyzer_eval(E0.s1[1].a == 'c'); // expected-warning{{UNKNOWN}} 230 clang_analyzer_eval(E0.s1[1].b == 'd'); // expected-warning{{UNKNOWN}} 231 clang_analyzer_eval(E0.s2 == 0); // expected-warning{{UNKNOWN}} 232 free(E0.s2); // no warning 233 return 0; 234 } 235 236 // Test global parameters. 237 struct aa a15 = {{1, 2, 3, 4}, 0}; 238 239 int f15() { 240 a15.s2 = strdup("hello"); 241 char input[] = {'a', 'b', 'c', 'd'}; 242 memcpy(a15.s1, input, 4); 243 clang_analyzer_eval(a15.s1[0] == 'a'); // expected-warning{{UNKNOWN}} 244 clang_analyzer_eval(a15.s1[1] == 'b'); // expected-warning{{UNKNOWN}} 245 clang_analyzer_eval(a15.s1[2] == 'c'); // expected-warning{{UNKNOWN}} 246 clang_analyzer_eval(a15.s1[3] == 'd'); // expected-warning{{UNKNOWN}} 247 clang_analyzer_eval(a15.s2 == 0); // expected-warning{{UNKNOWN}} 248 free(a15.s2); // no warning 249 return 0; 250 } 251 252 // Test array of 0 sized elements. 253 struct empty {}; 254 struct gg { 255 struct empty s1[4]; 256 char * s2; 257 }; 258 259 int f16() { 260 struct gg g0 = {{}, 0}; 261 g0.s2 = strdup("hello"); 262 char input[] = {'a', 'b', 'c', 'd'}; 263 memcpy(g0.s1, input, 4); 264 clang_analyzer_eval(*(int*)(&g0.s1[0]) == 'a'); // expected-warning{{UNKNOWN}}\ 265 expected-warning{{Potential leak of memory pointed to by 'g0.s2'}} 266 clang_analyzer_eval(*(int*)(&g0.s1[1]) == 'b'); // expected-warning{{UNKNOWN}} 267 clang_analyzer_eval(*(int*)(&g0.s1[2]) == 'c'); // expected-warning{{UNKNOWN}} 268 clang_analyzer_eval(*(int*)(&g0.s1[3]) == 'd'); // expected-warning{{UNKNOWN}} 269 clang_analyzer_eval(g0.s2 == 0); // expected-warning{{UNKNOWN}} 270 free(g0.s2); // no warning 271 return 0; 272 } 273 274 // Test array of 0 elements. 275 struct hh { 276 char s1[0]; 277 char * s2; 278 }; 279 280 int f17() { 281 struct hh h0; 282 h0.s2 = strdup("hello"); 283 char input[] = {'a', 'b', 'c', 'd'}; 284 memcpy(h0.s1, input, 4); 285 clang_analyzer_eval(h0.s1[0] == 'a'); // expected-warning{{UNKNOWN}}\ 286 expected-warning{{Potential leak of memory pointed to by 'h0.s2'}} 287 clang_analyzer_eval(h0.s2 == 0); // expected-warning{{UNKNOWN}} 288 free(h0.s2); // no warning 289 return 0; 290 } 291 292 // Test writing past the array. 293 struct ii { 294 char s1[4]; 295 int i; 296 int j; 297 char * s2; 298 }; 299 300 int f18() { 301 struct ii i18 = {{1, 2, 3, 4}, 5, 6}; 302 i18.i = 10; 303 i18.j = 11; 304 i18.s2 = strdup("hello"); 305 char input[100] = {3}; 306 memcpy(i18.s1, input, 100); 307 clang_analyzer_eval(i18.s1[0] == 1); // expected-warning{{UNKNOWN}}\ 308 expected-warning{{Potential leak of memory pointed to by 'i18.s2'}} 309 clang_analyzer_eval(i18.s1[1] == 2); // expected-warning{{UNKNOWN}} 310 clang_analyzer_eval(i18.s1[2] == 3); // expected-warning{{UNKNOWN}} 311 clang_analyzer_eval(i18.s1[3] == 4); // expected-warning{{UNKNOWN}} 312 clang_analyzer_eval(i18.i == 10); // expected-warning{{UNKNOWN}} 313 clang_analyzer_eval(i18.j == 11); // expected-warning{{UNKNOWN}} 314 return 0; 315 } 316 317 int f181() { 318 struct ii i181 = {{1, 2, 3, 4}, 5, 6}; 319 i181.i = 10; 320 i181.j = 11; 321 i181.s2 = strdup("hello"); 322 char input[100] = {3}; 323 memcpy(i181.s1, input, 5); // invalidate the whole region of i181 324 clang_analyzer_eval(i181.s1[0] == 1); // expected-warning{{UNKNOWN}}\ 325 expected-warning{{Potential leak of memory pointed to by 'i181.s2'}} 326 clang_analyzer_eval(i181.s1[1] == 2); // expected-warning{{UNKNOWN}} 327 clang_analyzer_eval(i181.s1[2] == 3); // expected-warning{{UNKNOWN}} 328 clang_analyzer_eval(i181.s1[3] == 4); // expected-warning{{UNKNOWN}} 329 clang_analyzer_eval(i181.i == 10); // expected-warning{{UNKNOWN}} 330 clang_analyzer_eval(i181.j == 11); // expected-warning{{UNKNOWN}} 331 return 0; 332 } 333 334 // Test array with a symbolic offset. 335 struct jj { 336 char s1[2]; 337 char * s2; 338 }; 339 340 struct JJ { 341 struct jj s1[3]; 342 char * s2; 343 }; 344 345 int f19(int i) { 346 struct JJ J0 = {{{1, 2, 0}, {3, 4, 0}, {5, 6, 0}}, 0}; 347 J0.s2 = strdup("hello"); 348 J0.s1[0].s2 = strdup("hello"); 349 J0.s1[1].s2 = strdup("hi"); 350 J0.s1[2].s2 = strdup("world"); 351 char input[2] = {'a', 'b'}; 352 memcpy(J0.s1[i].s1, input, 2); 353 clang_analyzer_eval(J0.s1[0].s1[0] == 1); // expected-warning{{UNKNOWN}}\ 354 expected-warning{{Potential leak of memory pointed to by field 's2'}}\ 355 expected-warning{{Potential leak of memory pointed to by 'J0.s2'}} 356 clang_analyzer_eval(J0.s1[0].s1[1] == 2); // expected-warning{{UNKNOWN}} 357 clang_analyzer_eval(J0.s1[1].s1[0] == 3); // expected-warning{{UNKNOWN}} 358 clang_analyzer_eval(J0.s1[1].s1[1] == 4); // expected-warning{{UNKNOWN}} 359 clang_analyzer_eval(J0.s1[2].s1[0] == 5); // expected-warning{{UNKNOWN}} 360 clang_analyzer_eval(J0.s1[2].s1[1] == 6); // expected-warning{{UNKNOWN}} 361 clang_analyzer_eval(J0.s1[i].s1[0] == 5); // expected-warning{{UNKNOWN}} 362 clang_analyzer_eval(J0.s1[i].s1[1] == 6); // expected-warning{{UNKNOWN}} 363 // FIXME: memory leak warning for J0.s2 should be emitted here instead of after memcpy call. 364 return 0; // no warning 365 } 366 367 // Test array with its super region having symbolic offseted regions. 368 int f20(int i) { 369 struct aa * a20 = malloc(sizeof(struct aa) * 2); 370 a20[0].s1[0] = 1; 371 a20[0].s1[1] = 2; 372 a20[0].s1[2] = 3; 373 a20[0].s1[3] = 4; 374 a20[0].s2 = strdup("hello"); 375 a20[1].s1[0] = 5; 376 a20[1].s1[1] = 6; 377 a20[1].s1[2] = 7; 378 a20[1].s1[3] = 8; 379 a20[1].s2 = strdup("world"); 380 a20[i].s2 = strdup("hola"); 381 char input[] = {'a', 'b', 'c', 'd'}; 382 memcpy(a20[0].s1, input, 4); 383 clang_analyzer_eval(a20[0].s1[0] == 1); // expected-warning{{UNKNOWN}} 384 clang_analyzer_eval(a20[0].s1[1] == 1); // expected-warning{{UNKNOWN}} 385 clang_analyzer_eval(a20[0].s1[2] == 1); // expected-warning{{UNKNOWN}} 386 clang_analyzer_eval(a20[0].s1[3] == 1); // expected-warning{{UNKNOWN}} 387 clang_analyzer_eval(a20[0].s2 == 0); // expected-warning{{UNKNOWN}} 388 clang_analyzer_eval(a20[1].s1[0] == 1); // expected-warning{{UNKNOWN}} 389 clang_analyzer_eval(a20[1].s1[1] == 1); // expected-warning{{UNKNOWN}} 390 clang_analyzer_eval(a20[1].s1[2] == 1); // expected-warning{{UNKNOWN}} 391 clang_analyzer_eval(a20[1].s1[3] == 1); // expected-warning{{UNKNOWN}} 392 clang_analyzer_eval(a20[1].s2 == 0); // expected-warning{{UNKNOWN}} 393 clang_analyzer_eval(a20[i].s1[0] == 1); // expected-warning{{UNKNOWN}} 394 clang_analyzer_eval(a20[i].s1[1] == 1); // expected-warning{{UNKNOWN}} 395 clang_analyzer_eval(a20[i].s1[2] == 1); // expected-warning{{UNKNOWN}} 396 clang_analyzer_eval(a20[i].s1[3] == 1); // expected-warning{{UNKNOWN}} 397 clang_analyzer_eval(a20[i].s2 == 0); // expected-warning{{UNKNOWN}}\ 398 expected-warning{{Potential leak of memory pointed to by 'a20'}} 399 400 return 0; 401 } 402 403 // Test array's region and super region both having symbolic offsets. 404 int f21(int i) { 405 struct aa * a21 = malloc(sizeof(struct aa) * 2); 406 a21[0].s1[0] = 1; 407 a21[0].s1[1] = 2; 408 a21[0].s1[2] = 3; 409 a21[0].s1[3] = 4; 410 a21[0].s2 = 0; 411 a21[1].s1[0] = 5; 412 a21[1].s1[1] = 6; 413 a21[1].s1[2] = 7; 414 a21[1].s1[3] = 8; 415 a21[1].s2 = 0; 416 a21[i].s2 = strdup("hello"); 417 a21[i].s1[0] = 1; 418 a21[i].s1[1] = 2; 419 a21[i].s1[2] = 3; 420 a21[i].s1[3] = 4; 421 char input[] = {'a', 'b', 'c', 'd'}; 422 memcpy(a21[i].s1, input, 4); 423 clang_analyzer_eval(a21[0].s1[0] == 1); // expected-warning{{UNKNOWN}} 424 clang_analyzer_eval(a21[0].s1[1] == 1); // expected-warning{{UNKNOWN}} 425 clang_analyzer_eval(a21[0].s1[2] == 1); // expected-warning{{UNKNOWN}} 426 clang_analyzer_eval(a21[0].s1[3] == 1); // expected-warning{{UNKNOWN}} 427 clang_analyzer_eval(a21[0].s2 == 0); // expected-warning{{UNKNOWN}} 428 clang_analyzer_eval(a21[1].s1[0] == 1); // expected-warning{{UNKNOWN}} 429 clang_analyzer_eval(a21[1].s1[1] == 1); // expected-warning{{UNKNOWN}} 430 clang_analyzer_eval(a21[1].s1[2] == 1); // expected-warning{{UNKNOWN}} 431 clang_analyzer_eval(a21[1].s1[3] == 1); // expected-warning{{UNKNOWN}} 432 clang_analyzer_eval(a21[1].s2 == 0); // expected-warning{{UNKNOWN}} 433 clang_analyzer_eval(a21[i].s1[0] == 1); // expected-warning{{UNKNOWN}} 434 clang_analyzer_eval(a21[i].s1[1] == 1); // expected-warning{{UNKNOWN}} 435 clang_analyzer_eval(a21[i].s1[2] == 1); // expected-warning{{UNKNOWN}} 436 clang_analyzer_eval(a21[i].s1[3] == 1); // expected-warning{{UNKNOWN}} 437 clang_analyzer_eval(a21[i].s2 == 0); // expected-warning{{UNKNOWN}}\ 438 expected-warning{{Potential leak of memory pointed to by 'a21'}} 439 440 return 0; 441 } 442 443 // Test regions aliasing other regions. 444 struct ll { 445 char s1[4]; 446 char * s2; 447 }; 448 449 struct mm { 450 char s3[4]; 451 char * s4; 452 }; 453 454 int f24() { 455 struct ll l24 = {{1, 2, 3, 4}, 0}; 456 struct mm * m24 = (struct mm *)&l24; 457 m24->s4 = strdup("hello"); 458 char input[] = {1, 2, 3, 4}; 459 memcpy(m24->s3, input, 4); 460 clang_analyzer_eval(m24->s3[0] == 1); // expected-warning{{UNKNOWN}} 461 clang_analyzer_eval(m24->s3[1] == 1); // expected-warning{{UNKNOWN}} 462 clang_analyzer_eval(m24->s3[2] == 1); // expected-warning{{UNKNOWN}} 463 clang_analyzer_eval(m24->s3[3] == 1); // expected-warning{{UNKNOWN}} 464 clang_analyzer_eval(l24.s1[0] == 1); // expected-warning{{UNKNOWN}} 465 clang_analyzer_eval(l24.s1[1] == 1); // expected-warning{{UNKNOWN}} 466 clang_analyzer_eval(l24.s1[2] == 1); // expected-warning{{UNKNOWN}} 467 clang_analyzer_eval(l24.s1[3] == 1); // expected-warning{{UNKNOWN}}\ 468 expected-warning{{Potential leak of memory pointed to by field 's4'}} 469 return 0; 470 } 471 472 // Test region with potential aliasing and symbolic offsets. 473 // Store assumes no aliasing. 474 int f25(int i, int j, struct ll * l, struct mm * m) { 475 m->s4 = strdup("hola"); // m->s4 not tracked 476 m->s3[0] = 1; 477 m->s3[1] = 2; 478 m->s3[2] = 3; 479 m->s3[3] = 4; 480 m->s3[j] = 5; // invalidates m->s3 481 l->s2 = strdup("hello"); // l->s2 not tracked 482 l->s1[0] = 6; 483 l->s1[1] = 7; 484 l->s1[2] = 8; 485 l->s1[3] = 9; 486 l->s1[i] = 10; // invalidates l->s1 487 char input[] = {1, 2, 3, 4}; 488 memcpy(m->s3, input, 4); // does not invalidate l->s1[i] 489 clang_analyzer_eval(m->s3[0] == 1); // expected-warning{{UNKNOWN}} 490 clang_analyzer_eval(m->s3[1] == 1); // expected-warning{{UNKNOWN}} 491 clang_analyzer_eval(m->s3[2] == 1); // expected-warning{{UNKNOWN}} 492 clang_analyzer_eval(m->s3[3] == 1); // expected-warning{{UNKNOWN}} 493 clang_analyzer_eval(m->s3[i] == 1); // expected-warning{{UNKNOWN}} 494 clang_analyzer_eval(m->s3[j] == 1); // expected-warning{{UNKNOWN}} 495 clang_analyzer_eval(l->s1[0] == 1); // expected-warning{{UNKNOWN}} 496 clang_analyzer_eval(l->s1[1] == 1); // expected-warning{{UNKNOWN}} 497 clang_analyzer_eval(l->s1[2] == 1); // expected-warning{{UNKNOWN}} 498 clang_analyzer_eval(l->s1[3] == 1); // expected-warning{{UNKNOWN}} 499 clang_analyzer_eval(l->s1[i] == 1); // expected-warning{{FALSE}} 500 clang_analyzer_eval(l->s1[j] == 1); // expected-warning{{UNKNOWN}} 501 return 0; 502 } 503 504 // Test size with symbolic size argument. 505 int f26(int i) { 506 struct aa a26 = {{1, 2, 3, 4}, 0}; 507 a26.s2 = strdup("hello"); 508 char input[] = {'a', 'b', 'c', 'd'}; 509 memcpy(a26.s1, input, i); // i assumed in bound 510 clang_analyzer_eval(a26.s1[0] == 1); // expected-warning{{UNKNOWN}} 511 clang_analyzer_eval(a26.s1[1] == 1); // expected-warning{{UNKNOWN}} 512 clang_analyzer_eval(a26.s1[2] == 1); // expected-warning{{UNKNOWN}} 513 clang_analyzer_eval(a26.s1[3] == 1); // expected-warning{{UNKNOWN}}\ 514 expected-warning{{Potential leak of memory pointed to by 'a26.s2'}} 515 return 0; 516 } 517 518 // Test sizeof as a size argument. 519 int f261() { 520 struct aa a261 = {{1, 2, 3, 4}, 0}; 521 a261.s2 = strdup("hello"); 522 char input[] = {'a', 'b', 'c', 'd'}; 523 memcpy(a261.s1, input, sizeof(a261.s1)); 524 clang_analyzer_eval(a261.s1[0] == 1); // expected-warning{{UNKNOWN}} 525 clang_analyzer_eval(a261.s1[1] == 1); // expected-warning{{UNKNOWN}} 526 clang_analyzer_eval(a261.s1[2] == 1); // expected-warning{{UNKNOWN}} 527 clang_analyzer_eval(a261.s1[3] == 1); // expected-warning{{UNKNOWN}}\ 528 expected-warning{{Potential leak of memory pointed to by 'a261.s2'}} 529 return 0; 530 } 531 532 // Test negative size argument. 533 int f262() { 534 struct aa a262 = {{1, 2, 3, 4}, 0}; 535 a262.s2 = strdup("hello"); 536 char input[] = {'a', 'b', 'c', 'd'}; 537 memcpy(a262.s1, input, -1); 538 clang_analyzer_eval(a262.s1[0] == 1); // expected-warning{{UNKNOWN}}\ 539 expected-warning{{Potential leak of memory pointed to by 'a262.s2'}} 540 clang_analyzer_eval(a262.s1[1] == 1); // expected-warning{{UNKNOWN}} 541 clang_analyzer_eval(a262.s1[2] == 1); // expected-warning{{UNKNOWN}} 542 clang_analyzer_eval(a262.s1[3] == 1); // expected-warning{{UNKNOWN}} 543 return 0; 544 } 545 546 // Test size argument being an unknown value. 547 struct xx { 548 char s1[4]; 549 char * s2; 550 }; 551 552 int f263(int n, char * len) { 553 struct xx x263 = {0}; 554 x263.s2 = strdup("hello"); 555 char input[] = {'a', 'b', 'c', 'd'}; 556 memcpy(x263.s1, input, *(len + n)); 557 clang_analyzer_eval(x263.s1[0] == 0); // expected-warning{{UNKNOWN}} 558 clang_analyzer_eval(x263.s1[1] == 0); // expected-warning{{UNKNOWN}} 559 clang_analyzer_eval(x263.s1[2] == 0); // expected-warning{{UNKNOWN}} 560 clang_analyzer_eval(x263.s1[3] == 0); // expected-warning{{UNKNOWN}} 561 clang_analyzer_eval(x263.s2 == 0); // expected-warning{{UNKNOWN}} 562 return 0; // expected-warning{{Potential leak of memory pointed to by 'x263.s2'}} 563 } 564 565 566 // Test casting regions with symbolic offseted sub regions. 567 int f27(int i) { 568 struct mm m27 = {{1, 2, 3, 4}, 0}; 569 m27.s4 = strdup("hello"); 570 m27.s3[i] = 5; 571 char input[] = {'a', 'b', 'c', 'd'}; 572 memcpy(((struct ll*)(&m27))->s1, input, 4); 573 clang_analyzer_eval(m27.s3[0] == 1); // expected-warning{{UNKNOWN}} 574 clang_analyzer_eval(m27.s3[1] == 1); // expected-warning{{UNKNOWN}} 575 clang_analyzer_eval(m27.s3[2] == 1); // expected-warning{{UNKNOWN}} 576 clang_analyzer_eval(m27.s3[3] == 1); // expected-warning{{UNKNOWN}} 577 clang_analyzer_eval(m27.s3[i] == 1); // expected-warning{{UNKNOWN}}\ 578 expected-warning{{Potential leak of memory pointed to by 'm27.s4'}} 579 return 0; 580 } 581 582 int f28(int i, int j, int k, int l) { 583 struct mm m28[2]; 584 m28[i].s4 = strdup("hello"); 585 m28[j].s3[k] = 1; 586 struct ll * l28 = (struct ll*)(&m28[1]); 587 l28->s1[l] = 2; 588 char input[] = {'a', 'b', 'c', 'd'}; 589 memcpy(l28->s1, input, 4); 590 clang_analyzer_eval(m28[0].s3[0] == 1); // expected-warning{{UNKNOWN}} 591 clang_analyzer_eval(m28[0].s3[1] == 1); // expected-warning{{UNKNOWN}} 592 clang_analyzer_eval(m28[0].s3[2] == 1); // expected-warning{{UNKNOWN}} 593 clang_analyzer_eval(m28[0].s3[3] == 1); // expected-warning{{UNKNOWN}} 594 clang_analyzer_eval(m28[1].s3[0] == 1); // expected-warning{{UNKNOWN}} 595 clang_analyzer_eval(m28[1].s3[1] == 1); // expected-warning{{UNKNOWN}} 596 clang_analyzer_eval(m28[1].s3[2] == 1); // expected-warning{{UNKNOWN}} 597 clang_analyzer_eval(m28[1].s3[3] == 1); // expected-warning{{UNKNOWN}} 598 clang_analyzer_eval(m28[i].s3[0] == 1); // expected-warning{{UNKNOWN}} 599 clang_analyzer_eval(m28[i].s3[1] == 1); // expected-warning{{UNKNOWN}} 600 clang_analyzer_eval(m28[i].s3[2] == 1); // expected-warning{{UNKNOWN}} 601 clang_analyzer_eval(m28[i].s3[3] == 1); // expected-warning{{UNKNOWN}} 602 clang_analyzer_eval(m28[j].s3[k] == 1); // expected-warning{{UNKNOWN}} 603 clang_analyzer_eval(l28->s1[l] == 2); // expected-warning{{UNKNOWN}} 604 return 0; 605 } 606 607 int f29(int i, int j, int k, int l, int m) { 608 struct mm m29[2]; 609 m29[i].s4 = strdup("hello"); 610 m29[j].s3[k] = 1; 611 struct ll * l29 = (struct ll*)(&m29[l]); 612 l29->s1[m] = 2; 613 char input[] = {'a', 'b', 'c', 'd'}; 614 memcpy(l29->s1, input, 4); 615 clang_analyzer_eval(m29[0].s3[0] == 1); // expected-warning{{UNKNOWN}} 616 clang_analyzer_eval(m29[0].s3[1] == 1); // expected-warning{{UNKNOWN}} 617 clang_analyzer_eval(m29[0].s3[2] == 1); // expected-warning{{UNKNOWN}} 618 clang_analyzer_eval(m29[0].s3[3] == 1); // expected-warning{{UNKNOWN}} 619 clang_analyzer_eval(m29[1].s3[0] == 1); // expected-warning{{UNKNOWN}} 620 clang_analyzer_eval(m29[1].s3[1] == 1); // expected-warning{{UNKNOWN}} 621 clang_analyzer_eval(m29[1].s3[2] == 1); // expected-warning{{UNKNOWN}} 622 clang_analyzer_eval(m29[1].s3[3] == 1); // expected-warning{{UNKNOWN}} 623 clang_analyzer_eval(m29[i].s3[0] == 1); // expected-warning{{UNKNOWN}} 624 clang_analyzer_eval(m29[i].s3[1] == 1); // expected-warning{{UNKNOWN}} 625 clang_analyzer_eval(m29[i].s3[2] == 1); // expected-warning{{UNKNOWN}} 626 clang_analyzer_eval(m29[i].s3[3] == 1); // expected-warning{{UNKNOWN}} 627 clang_analyzer_eval(m29[j].s3[k] == 1); // expected-warning{{TRUE}}\ 628 expected-warning{{Potential leak of memory pointed to by field 's4'}} 629 clang_analyzer_eval(l29->s1[m] == 2); // expected-warning{{UNKNOWN}} 630 return 0; 631 } 632 633 // Test unions' fields. 634 union uu { 635 char x; 636 char s1[4]; 637 }; 638 639 int f30() { 640 union uu u30 = { .s1 = {1, 2, 3, 4}}; 641 char input[] = {1, 2, 3, 4}; 642 memcpy(u30.s1, input, 4); 643 clang_analyzer_eval(u30.s1[0] == 1); // expected-warning{{UNKNOWN}} 644 clang_analyzer_eval(u30.s1[1] == 1); // expected-warning{{UNKNOWN}} 645 clang_analyzer_eval(u30.s1[2] == 1); // expected-warning{{UNKNOWN}} 646 clang_analyzer_eval(u30.s1[3] == 1); // expected-warning{{UNKNOWN}} 647 clang_analyzer_eval(u30.x == 1); // expected-warning{{UNKNOWN}} 648 return 0; 649 } 650 651 struct kk { 652 union uu u; 653 char * s2; 654 }; 655 656 int f31() { 657 struct kk k31; 658 k31.s2 = strdup("hello"); 659 k31.u.x = 1; 660 char input[] = {'a', 'b', 'c', 'd'}; 661 memcpy(k31.u.s1, input, 4); 662 clang_analyzer_eval(k31.u.s1[0] == 1); // expected-warning{{UNKNOWN}}\ 663 expected-warning{{Potential leak of memory pointed to by 'k31.s2'}} 664 clang_analyzer_eval(k31.u.s1[1] == 1); // expected-warning{{UNKNOWN}} 665 clang_analyzer_eval(k31.u.s1[2] == 1); // expected-warning{{UNKNOWN}} 666 clang_analyzer_eval(k31.u.s1[3] == 1); // expected-warning{{UNKNOWN}} 667 clang_analyzer_eval(k31.u.x == 1); // expected-warning{{UNKNOWN}} 668 // FIXME: memory leak warning for k31.s2 should be emitted here. 669 return 0; 670 } 671 672 union vv { 673 int x; 674 char * s2; 675 }; 676 677 int f32() { 678 union vv v32; 679 v32.s2 = strdup("hello"); 680 char input[] = {'a', 'b', 'c', 'd'}; 681 memcpy(v32.s2, input, 4); 682 clang_analyzer_eval(v32.s2[0] == 1); // expected-warning{{UNKNOWN}} 683 clang_analyzer_eval(v32.s2[1] == 1); // expected-warning{{UNKNOWN}} 684 clang_analyzer_eval(v32.s2[2] == 1); // expected-warning{{UNKNOWN}} 685 clang_analyzer_eval(v32.s2[3] == 1); // expected-warning{{UNKNOWN}}\ 686 expected-warning{{Potential leak of memory pointed to by 'v32.s2'}} 687 return 0; 688 } 689 690 struct nn { 691 int s1; 692 int i; 693 int j; 694 int k; 695 char * s2; 696 }; 697 698 // Test bad types to dest buffer. 699 int f33() { 700 struct nn n33 = {1, 2, 3, 4, 0}; 701 n33.s2 = strdup("hello"); 702 char input[] = {'a', 'b', 'c', 'd'}; 703 memcpy(n33.s1, input, 4); // expected-warning{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'}} 704 clang_analyzer_eval(n33.i == 2); // expected-warning{{TRUE}} 705 clang_analyzer_eval(n33.j == 3); // expected-warning{{TRUE}} 706 clang_analyzer_eval(n33.k == 4); // expected-warning{{TRUE}} 707 clang_analyzer_eval(((char*)(n33.s1))[0] == 1); // expected-warning{{UNKNOWN}}\ 708 expected-warning{{cast to 'char *' from smaller integer type 'int'}} 709 clang_analyzer_eval(((char*)(n33.s1))[1] == 1); // expected-warning{{UNKNOWN}}\ 710 expected-warning{{cast to 'char *' from smaller integer type 'int'}} 711 clang_analyzer_eval(((char*)(n33.s1))[2] == 1); // expected-warning{{UNKNOWN}}\ 712 expected-warning{{cast to 'char *' from smaller integer type 'int'}} 713 clang_analyzer_eval(((char*)(n33.s1))[3] == 1); // expected-warning{{UNKNOWN}}\ 714 expected-warning{{cast to 'char *' from smaller integer type 'int'}} 715 clang_analyzer_eval(n33.s2 == 0); //expected-warning{{UNKNOWN}} 716 return 0; // expected-warning{{Potential leak of memory pointed to by 'n33.s2'}} 717 } 718 719 // Test destination buffer being an unknown value. 720 struct ww { 721 int s1[4]; 722 char s2; 723 }; 724 725 int f34(struct ww * w34, int n) { 726 w34->s2 = 3; 727 char input[] = {'a', 'b', 'c', 'd'}; 728 memcpy(w34->s1 + n, input , 4); 729 clang_analyzer_eval(w34->s1[0] == 0); // expected-warning{{UNKNOWN}} 730 clang_analyzer_eval(w34->s1[1] == 0); // expected-warning{{UNKNOWN}} 731 clang_analyzer_eval(w34->s1[2] == 0); // expected-warning{{UNKNOWN}} 732 clang_analyzer_eval(w34->s1[3] == 0); // expected-warning{{UNKNOWN}} 733 clang_analyzer_eval(w34->s1[n] == 0); // expected-warning{{UNKNOWN}} 734 clang_analyzer_eval(w34->s2 == 3); // expected-warning{{TRUE}} 735 return 0; 736 } 737 738 // Test dest buffer as an element region with a symbolic index and size parameter as a symbolic value. 739 struct yy { 740 char s1[4]; 741 char * s2; 742 }; 743 744 int f35(int i, int n) { 745 struct yy y35 = {{1, 2, 3, 4}, 0}; 746 y35.s2 = strdup("hello"); 747 char input[] = {'a', 'b', 'c', 'd'}; 748 memcpy(&(y35.s1[i]), input, n); 749 clang_analyzer_eval(y35.s1[0] == 0); // expected-warning{{UNKNOWN}} 750 clang_analyzer_eval(y35.s1[1] == 0); // expected-warning{{UNKNOWN}} 751 clang_analyzer_eval(y35.s1[2] == 0); // expected-warning{{UNKNOWN}} 752 clang_analyzer_eval(y35.s1[3] == 0); // expected-warning{{UNKNOWN}} 753 clang_analyzer_eval(y35.s1[i] == 0); // expected-warning{{UNKNOWN}} 754 clang_analyzer_eval(y35.s2 == 0); // expected-warning{{UNKNOWN}} 755 return 0; // expected-warning{{Potential leak of memory pointed to by 'y35.s2'}} 756 } 757 758 // Test regions with negative offsets. 759 struct zz { 760 char s1[4]; 761 int s2; 762 }; 763 764 int f36(struct zz * z36) { 765 766 char input[] = {'a', 'b', 'c', 'd'}; 767 z36->s1[0] = 0; 768 z36->s1[1] = 1; 769 z36->s1[2] = 2; 770 z36->s1[3] = 3; 771 z36->s2 = 10; 772 773 z36 = z36 - 1; // Decrement by 8 bytes (struct zz is 8 bytes). 774 775 z36->s1[0] = 4; 776 z36->s1[1] = 5; 777 z36->s1[2] = 6; 778 z36->s1[3] = 7; 779 z36->s2 = 11; 780 781 memcpy(z36->s1, input, 4); 782 783 clang_analyzer_eval(z36->s1[0] == 1); // expected-warning{{UNKNOWN}} 784 clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{UNKNOWN}} 785 clang_analyzer_eval(z36->s1[2] == 1); // expected-warning{{UNKNOWN}} 786 clang_analyzer_eval(z36->s1[3] == 1); // expected-warning{{UNKNOWN}} 787 clang_analyzer_eval(z36->s2 == 11); // expected-warning{{TRUE}} 788 789 z36 = z36 + 1; // Increment back. 790 791 clang_analyzer_eval(z36->s1[0] == 0); // expected-warning{{TRUE}} 792 clang_analyzer_eval(z36->s1[1] == 1); // expected-warning{{TRUE}} 793 clang_analyzer_eval(z36->s1[2] == 2); // expected-warning{{TRUE}} 794 clang_analyzer_eval(z36->s1[3] == 3); // expected-warning{{TRUE}} 795 clang_analyzer_eval(z36->s2 == 10); // expected-warning{{TRUE}} 796 797 return 0; 798 } 799 800 int f37(struct zz * z37) { 801 802 char input[] = {'a', 'b', 'c', 'd'}; 803 z37->s1[0] = 0; 804 z37->s1[1] = 1; 805 z37->s1[2] = 2; 806 z37->s1[3] = 3; 807 z37->s2 = 10; 808 809 z37 = (struct zz *)((char*)(z37) - 4); // Decrement by 4 bytes (struct zz is 8 bytes). 810 811 z37->s1[0] = 4; 812 z37->s1[1] = 5; 813 z37->s1[2] = 6; 814 z37->s1[3] = 7; 815 z37->s2 = 11; 816 817 memcpy(z37->s1, input, 4); 818 819 clang_analyzer_eval(z37->s1[0] == 1); // expected-warning{{UNKNOWN}} 820 clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}} 821 clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}} 822 clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}} 823 clang_analyzer_eval(z37->s2 == 11); // expected-warning{{TRUE}} 824 825 z37 = (struct zz *)((char*)(z37) + 4); // Increment back. 826 827 clang_analyzer_eval(z37->s1[0] == 11); // expected-warning{{TRUE}} 828 clang_analyzer_eval(z37->s1[1] == 1); // expected-warning{{UNKNOWN}} 829 clang_analyzer_eval(z37->s1[2] == 1); // expected-warning{{UNKNOWN}} 830 clang_analyzer_eval(z37->s1[3] == 1); // expected-warning{{UNKNOWN}} 831 clang_analyzer_eval(z37->s2 == 10); // expected-warning{{TRUE}} 832 833 return 0; 834 } 835 836 int f38(struct zz * z38) { 837 838 char input[] = {'a', 'b', 'c', 'd'}; 839 z38->s1[0] = 0; 840 z38->s1[1] = 1; 841 z38->s1[2] = 2; 842 z38->s1[3] = 3; 843 z38->s2 = 10; 844 845 z38 = (struct zz *)((char*)(z38) - 2); // Decrement by 2 bytes (struct zz is 8 bytes). 846 847 z38->s1[0] = 4; 848 z38->s1[1] = 5; 849 z38->s1[2] = 6; 850 z38->s1[3] = 7; 851 z38->s2 = 11; 852 853 memcpy(z38->s1, input, 4); 854 855 clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}} 856 clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}} 857 clang_analyzer_eval(z38->s1[2] == 1); // expected-warning{{UNKNOWN}} 858 clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}} 859 clang_analyzer_eval(z38->s2 == 11); // expected-warning{{TRUE}} 860 861 z38 = (struct zz *)((char*)(z38) + 2); // Increment back. 862 863 clang_analyzer_eval(z38->s1[0] == 1); // expected-warning{{UNKNOWN}} 864 clang_analyzer_eval(z38->s1[1] == 1); // expected-warning{{UNKNOWN}} 865 clang_analyzer_eval(z38->s1[2] == 11); // expected-warning{{TRUE}} 866 clang_analyzer_eval(z38->s1[3] == 1); // expected-warning{{UNKNOWN}} 867 clang_analyzer_eval(z38->s2 == 10); // expected-warning{{UNKNOWN}} 868 869 return 0; 870 } 871 872 // Test negative offsets with a different structure layout. 873 struct z0 { 874 int s2; 875 char s1[4]; 876 }; 877 878 int f39(struct z0 * d39) { 879 880 char input[] = {'a', 'b', 'c', 'd'}; 881 d39->s1[0] = 0; 882 d39->s1[1] = 1; 883 d39->s1[2] = 2; 884 d39->s1[3] = 3; 885 d39->s2 = 10; 886 887 d39 = (struct z0 *)((char*)(d39) - 2); // Decrement by 2 bytes (struct z0 is 8 bytes). 888 889 d39->s1[0] = 4; 890 d39->s1[1] = 5; 891 d39->s1[2] = 6; 892 d39->s1[3] = 7; 893 d39->s2 = 11; 894 895 memcpy(d39->s1, input, 4); 896 897 clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}} 898 clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}} 899 clang_analyzer_eval(d39->s1[2] == 1); // expected-warning{{UNKNOWN}} 900 clang_analyzer_eval(d39->s1[3] == 1); // expected-warning{{UNKNOWN}} 901 clang_analyzer_eval(d39->s2 == 11); // expected-warning{{TRUE}} 902 903 d39 = (struct z0 *)((char*)(d39) + 2); // Increment back. 904 905 clang_analyzer_eval(d39->s1[0] == 1); // expected-warning{{UNKNOWN}} 906 clang_analyzer_eval(d39->s1[1] == 1); // expected-warning{{UNKNOWN}} 907 clang_analyzer_eval(d39->s1[2] == 2); // expected-warning{{TRUE}} 908 clang_analyzer_eval(d39->s1[3] == 3); // expected-warning{{TRUE}} 909 // FIXME: d39->s2 should evaluate to at least UNKNOWN or FALSE, 910 // 'collectSubRegionBindings(...)' in RegionStore.cpp will need to 911 // handle a regions' upper boundary overflowing. 912 clang_analyzer_eval(d39->s2 == 10); // expected-warning{{TRUE}} 913 914 return 0; 915 } 916 917