1 // RUN: %clang_analyze_cc1 -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=unix.Stream \ 4 // RUN: -analyzer-config unix.Stream:Pedantic=true \ 5 // RUN: -analyzer-checker=debug.StreamTester \ 6 // RUN: -analyzer-checker=debug.ExprInspection 7 8 #include "Inputs/system-header-simulator.h" 9 10 void clang_analyzer_eval(int); 11 void clang_analyzer_dump(int); 12 void clang_analyzer_warnIfReached(void); 13 void StreamTesterChecker_make_feof_stream(FILE *); 14 void StreamTesterChecker_make_ferror_stream(FILE *); 15 void StreamTesterChecker_make_ferror_indeterminate_stream(FILE *); 16 17 void error_fopen(void) { 18 FILE *F = fopen("file", "r"); 19 if (!F) 20 return; 21 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 22 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 23 fclose(F); 24 } 25 26 void error_fdopen(int fd) { 27 FILE *F = fdopen(fd, "r"); 28 if (!F) 29 return; 30 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 31 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 32 fclose(F); 33 } 34 35 void error_freopen(void) { 36 FILE *F = fopen("file", "r"); 37 if (!F) 38 return; 39 F = freopen(0, "w", F); 40 if (!F) 41 return; 42 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 43 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 44 fclose(F); 45 } 46 47 void stream_error_feof(void) { 48 FILE *F = fopen("file", "r"); 49 if (!F) 50 return; 51 StreamTesterChecker_make_feof_stream(F); 52 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 53 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 54 clearerr(F); 55 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 56 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 57 StreamTesterChecker_make_ferror_indeterminate_stream(F); 58 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 59 fclose(F); 60 } 61 62 void stream_error_ferror(void) { 63 FILE *F = fopen("file", "r"); 64 if (!F) 65 return; 66 StreamTesterChecker_make_ferror_stream(F); 67 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 68 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 69 clearerr(F); 70 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 71 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 72 StreamTesterChecker_make_ferror_indeterminate_stream(F); 73 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 74 fclose(F); 75 } 76 77 void error_fread(void) { 78 FILE *F = tmpfile(); 79 if (!F) 80 return; 81 char Buf[10]; 82 int Ret = fread(Buf, 1, 10, F); 83 if (Ret == 10) { 84 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 85 } else { 86 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 87 if (feof(F)) { 88 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 89 fread(Buf, 1, 10, F); // expected-warning {{Read function called when stream is in EOF state}} 90 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 91 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 92 } 93 if (ferror(F)) { 94 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 95 fread(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 96 } 97 } 98 fclose(F); 99 Ret = fread(Buf, 1, 10, F); // expected-warning {{Use of a stream that might be already closed}} 100 } 101 102 void error_fwrite(void) { 103 FILE *F = tmpfile(); 104 if (!F) 105 return; 106 const char *Buf = "123456789"; 107 int Ret = fwrite(Buf, 1, 10, F); 108 if (Ret == 10) { 109 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 110 } else { 111 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 112 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 113 fwrite(0, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 114 } 115 fclose(F); 116 Ret = fwrite(0, 1, 10, F); // expected-warning {{Use of a stream that might be already closed}} 117 } 118 119 void error_fgetc(void) { 120 FILE *F = tmpfile(); 121 if (!F) 122 return; 123 int Ret = fgetc(F); 124 if (0 <= Ret && Ret <= 255) { 125 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 126 } else { 127 clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} 128 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 129 if (feof(F)) { 130 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 131 fgetc(F); // expected-warning {{Read function called when stream is in EOF state}} 132 } else { 133 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 134 fgetc(F); // expected-warning {{might be 'indeterminate'}} 135 } 136 } 137 fclose(F); 138 fgetc(F); // expected-warning {{Use of a stream that might be already closed}} 139 } 140 141 void error_fgets(void) { 142 FILE *F = tmpfile(); 143 char Buf[256]; 144 if (!F) 145 return; 146 char *Ret = fgets(Buf, sizeof(Buf), F); 147 if (Ret == Buf) { 148 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 149 } else { 150 clang_analyzer_eval(Ret == NULL); // expected-warning {{TRUE}} 151 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 152 if (feof(F)) { 153 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 154 fgets(Buf, sizeof(Buf), F); // expected-warning {{Read function called when stream is in EOF state}} 155 } else { 156 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 157 fgets(Buf, sizeof(Buf), F); // expected-warning {{might be 'indeterminate'}} 158 } 159 } 160 fclose(F); 161 fgets(Buf, sizeof(Buf), F); // expected-warning {{Use of a stream that might be already closed}} 162 } 163 164 void error_fputc(int fd) { 165 FILE *F = fdopen(fd, "w"); 166 if (!F) 167 return; 168 int Ret = fputc('X', F); 169 if (Ret == EOF) { 170 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 171 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 172 fputc('Y', F); // expected-warning {{might be 'indeterminate'}} 173 } else { 174 clang_analyzer_eval(Ret == 'X'); // expected-warning {{TRUE}} 175 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 176 fputc('Y', F); // no-warning 177 } 178 fclose(F); 179 fputc('A', F); // expected-warning {{Use of a stream that might be already closed}} 180 } 181 182 void error_fputs(void) { 183 FILE *F = tmpfile(); 184 if (!F) 185 return; 186 int Ret = fputs("XYZ", F); 187 if (Ret >= 0) { 188 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 189 fputs("QWD", F); // no-warning 190 } else { 191 clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} 192 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 193 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 194 fputs("QWD", F); // expected-warning {{might be 'indeterminate'}} 195 } 196 fclose(F); 197 fputs("ABC", F); // expected-warning {{Use of a stream that might be already closed}} 198 } 199 200 void error_fprintf(void) { 201 FILE *F = tmpfile(); 202 if (!F) 203 return; 204 int Ret = fprintf(F, "aaa"); 205 if (Ret >= 0) { 206 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 207 fprintf(F, "bbb"); // no-warning 208 } else { 209 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 210 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 211 fprintf(F, "bbb"); // expected-warning {{might be 'indeterminate'}} 212 } 213 fclose(F); 214 fprintf(F, "ccc"); // expected-warning {{Use of a stream that might be already closed}} 215 } 216 217 void error_fscanf(int *A) { 218 FILE *F = tmpfile(); 219 if (!F) 220 return; 221 int Ret = fscanf(F, "a%ib", A); 222 if (Ret >= 0) { 223 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 224 fscanf(F, "bbb"); // no-warning 225 } else { 226 if (ferror(F)) { 227 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 228 fscanf(F, "bbb"); // expected-warning {{might be 'indeterminate'}} 229 } else if (feof(F)) { 230 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 231 fscanf(F, "bbb"); // expected-warning {{is in EOF state}} 232 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 233 } else { 234 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 235 fscanf(F, "bbb"); // expected-warning {{might be 'indeterminate'}} 236 } 237 } 238 fclose(F); 239 fscanf(F, "ccc"); // expected-warning {{Use of a stream that might be already closed}} 240 } 241 242 void error_ungetc(int TestIndeterminate) { 243 FILE *F = tmpfile(); 244 if (!F) 245 return; 246 int Ret = ungetc('X', F); 247 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 248 if (Ret == EOF) { 249 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 250 } else { 251 clang_analyzer_eval(Ret == 'X'); // expected-warning {{TRUE}} 252 } 253 fputc('Y', F); // no-warning 254 if (TestIndeterminate) { 255 StreamTesterChecker_make_ferror_indeterminate_stream(F); 256 ungetc('X', F); // expected-warning {{might be 'indeterminate'}} 257 } 258 fclose(F); 259 ungetc('A', F); // expected-warning {{Use of a stream that might be already closed}} 260 } 261 262 void error_getdelim(char *P, size_t Sz) { 263 FILE *F = tmpfile(); 264 if (!F) 265 return; 266 ssize_t Ret = getdelim(&P, &Sz, '\t', F); 267 if (Ret >= 0) { 268 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 269 } else { 270 clang_analyzer_eval(Ret == -1); // expected-warning {{TRUE}} 271 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 272 if (feof(F)) { 273 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 274 getdelim(&P, &Sz, '\n', F); // expected-warning {{Read function called when stream is in EOF state}} 275 } else { 276 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 277 getdelim(&P, &Sz, '\n', F); // expected-warning {{might be 'indeterminate'}} 278 } 279 } 280 fclose(F); 281 getdelim(&P, &Sz, '\n', F); // expected-warning {{Use of a stream that might be already closed}} 282 } 283 284 void error_getline(char *P, size_t Sz) { 285 FILE *F = tmpfile(); 286 if (!F) 287 return; 288 ssize_t Ret = getline(&P, &Sz, F); 289 if (Ret >= 0) { 290 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 291 } else { 292 clang_analyzer_eval(Ret == -1); // expected-warning {{TRUE}} 293 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 294 if (feof(F)) { 295 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 296 getline(&P, &Sz, F); // expected-warning {{Read function called when stream is in EOF state}} 297 } else { 298 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 299 getline(&P, &Sz, F); // expected-warning {{might be 'indeterminate'}} 300 } 301 } 302 fclose(F); 303 getline(&P, &Sz, F); // expected-warning {{Use of a stream that might be already closed}} 304 } 305 306 void write_after_eof_is_allowed(void) { 307 FILE *F = tmpfile(); 308 if (!F) 309 return; 310 StreamTesterChecker_make_feof_stream(F); 311 if (fputs("QWD", F) >= 0) // no-warning 312 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 313 StreamTesterChecker_make_feof_stream(F); 314 if (fputc('Q', F) == 'Q') // no-warning 315 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 316 StreamTesterChecker_make_feof_stream(F); 317 if (fwrite("012345678", 1, 10, F) == 10) // no-warning 318 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 319 fclose(F); 320 } 321 322 void freadwrite_zerosize(FILE *F) { 323 size_t Ret; 324 Ret = fwrite(0, 1, 0, F); 325 clang_analyzer_dump(Ret); // expected-warning {{0 }} 326 Ret = fwrite(0, 0, 1, F); 327 clang_analyzer_dump(Ret); // expected-warning {{0 }} 328 Ret = fread(0, 1, 0, F); 329 clang_analyzer_dump(Ret); // expected-warning {{0 }} 330 Ret = fread(0, 0, 1, F); 331 clang_analyzer_dump(Ret); // expected-warning {{0 }} 332 } 333 334 void freadwrite_zerosize_eofstate(FILE *F) { 335 fwrite(0, 1, 0, F); 336 fwrite(0, 0, 1, F); 337 fread(0, 1, 0, F); // expected-warning {{Read function called when stream is in EOF state}} 338 fread(0, 0, 1, F); // expected-warning {{Read function called when stream is in EOF state}} 339 } 340 341 void error_fread_fwrite_zerosize(void) { 342 FILE *F = fopen("file", "r"); 343 if (!F) 344 return; 345 346 freadwrite_zerosize(F); 347 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 348 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 349 350 StreamTesterChecker_make_ferror_stream(F); 351 freadwrite_zerosize(F); 352 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 353 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 354 355 StreamTesterChecker_make_feof_stream(F); 356 freadwrite_zerosize_eofstate(F); 357 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 358 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 359 360 fclose(F); 361 } 362 363 void error_fseek(void) { 364 FILE *F = fopen("file", "r"); 365 if (!F) 366 return; 367 int rc = fseek(F, 1, SEEK_SET); 368 if (rc) { 369 clang_analyzer_eval(rc == -1); // expected-warning {{TRUE}} 370 int IsFEof = feof(F), IsFError = ferror(F); 371 // Get ferror or no error. 372 clang_analyzer_eval(IsFError); // expected-warning {{FALSE}} \ 373 // expected-warning {{TRUE}} 374 clang_analyzer_eval(IsFEof); // expected-warning {{FALSE}} 375 // Error flags should not change. 376 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 377 if (IsFError) 378 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 379 } else { 380 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 381 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 382 // Error flags should not change. 383 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 384 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 385 } 386 fclose(F); 387 } 388 389 void error_fseeko(void) { 390 FILE *F = fopen("file", "r"); 391 if (!F) 392 return; 393 int rc = fseeko(F, 1, SEEK_SET); 394 if (rc) { 395 // Get ferror or no error. 396 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} \ 397 // expected-warning {{TRUE}} 398 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 399 } else { 400 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 401 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 402 } 403 fclose(F); 404 } 405 406 void error_fseek_0(void) { 407 FILE *F = fopen("file", "r"); 408 if (!F) 409 return; 410 int rc = fseek(F, 0, SEEK_SET); 411 if (rc == -1) { 412 int IsFEof = feof(F), IsFError = ferror(F); 413 // Get ferror or no error, but not feof. 414 clang_analyzer_eval(IsFError); 415 // expected-warning@-1 {{FALSE}} 416 // expected-warning@-2 {{TRUE}} 417 clang_analyzer_eval(IsFEof); 418 // expected-warning@-1 {{FALSE}} 419 // Error flags should not change. 420 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 421 if (IsFError) 422 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 423 else 424 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 425 } else { 426 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 427 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 428 // Error flags should not change. 429 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 430 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 431 } 432 fclose(F); 433 } 434 435 void error_fseeko_0(void) { 436 FILE *F = fopen("file", "r"); 437 if (!F) 438 return; 439 int rc = fseeko(F, 0, SEEK_SET); 440 if (rc) { 441 int IsFEof = feof(F), IsFError = ferror(F); 442 // Get ferror or no error, but not feof. 443 clang_analyzer_eval(IsFError); 444 // expected-warning@-1 {{FALSE}} 445 // expected-warning@-2 {{TRUE}} 446 clang_analyzer_eval(IsFEof); 447 // expected-warning@-1 {{FALSE}} 448 } else { 449 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 450 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 451 } 452 fclose(F); 453 } 454 455 void error_ftell(int TestIndeterminate) { 456 FILE *F = fopen("file", "r"); 457 if (!F) 458 return; 459 long rc = ftell(F); 460 if (rc >= 0) 461 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 462 else 463 clang_analyzer_eval(rc == -1); // expected-warning {{TRUE}} 464 clang_analyzer_eval(feof(F) && ferror(F)); // expected-warning {{FALSE}} 465 StreamTesterChecker_make_feof_stream(F); 466 rc = ftell(F); 467 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 468 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 469 StreamTesterChecker_make_ferror_stream(F); 470 rc = ftell(F); 471 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 472 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 473 if (TestIndeterminate) { 474 StreamTesterChecker_make_ferror_indeterminate_stream(F); 475 ftell(F); // expected-warning {{might be 'indeterminate'}} 476 } 477 fclose(F); 478 } 479 480 void error_ftello(int TestIndeterminate) { 481 FILE *F = fopen("file", "r"); 482 if (!F) 483 return; 484 off_t rc = ftello(F); 485 if (rc >= 0) 486 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 487 else 488 clang_analyzer_eval(rc == -1); // expected-warning {{TRUE}} 489 clang_analyzer_eval(feof(F) && ferror(F)); // expected-warning {{FALSE}} 490 StreamTesterChecker_make_feof_stream(F); 491 rc = ftello(F); 492 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 493 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 494 StreamTesterChecker_make_ferror_stream(F); 495 rc = ftello(F); 496 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 497 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 498 if (TestIndeterminate) { 499 StreamTesterChecker_make_ferror_indeterminate_stream(F); 500 ftell(F); // expected-warning {{might be 'indeterminate'}} 501 } 502 fclose(F); 503 } 504 505 void error_fileno(void) { 506 FILE *F = fopen("file", "r"); 507 if (!F) 508 return; 509 int N = fileno(F); 510 clang_analyzer_eval(N >= 0); // expected-warning {{TRUE}} 511 clang_analyzer_eval(feof(F) && ferror(F)); // expected-warning {{FALSE}} 512 StreamTesterChecker_make_feof_stream(F); 513 N = fileno(F); 514 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 515 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 516 StreamTesterChecker_make_ferror_stream(F); 517 N = fileno(F); 518 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 519 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 520 StreamTesterChecker_make_ferror_indeterminate_stream(F); 521 fileno(F); // no warning 522 fclose(F); 523 } 524 525 void error_fflush_on_non_null_stream_clear_error_states(void) { 526 FILE *F0 = tmpfile(), *F1 = tmpfile(); 527 // `fflush` clears a non-EOF stream's error state. 528 if (F0) { 529 StreamTesterChecker_make_ferror_stream(F0); 530 if (fflush(F0) == 0) { // no-warning 531 clang_analyzer_eval(ferror(F0)); // expected-warning {{FALSE}} 532 clang_analyzer_eval(feof(F0)); // expected-warning {{FALSE}} 533 } 534 fclose(F0); 535 } 536 // `fflush` clears an EOF stream's error state. 537 if (F1) { 538 StreamTesterChecker_make_feof_stream(F1); 539 if (fflush(F1) == 0) { // no-warning 540 clang_analyzer_eval(ferror(F1)); // expected-warning {{FALSE}} 541 clang_analyzer_eval(feof(F1)); // expected-warning {{TRUE}} 542 } 543 fclose(F1); 544 } 545 } 546 547 void error_fflush_on_null_stream_clear_error_states(void) { 548 FILE *F0 = tmpfile(), *F1 = tmpfile(); 549 // `fflush` clears all stream's error states, while retains their EOF states. 550 if (F0 && F1) { 551 StreamTesterChecker_make_ferror_stream(F0); 552 StreamTesterChecker_make_feof_stream(F1); 553 if (fflush(NULL) == 0) { // no-warning 554 clang_analyzer_eval(ferror(F0)); // expected-warning {{FALSE}} 555 clang_analyzer_eval(feof(F0)); // expected-warning {{FALSE}} 556 clang_analyzer_eval(ferror(F1)); // expected-warning {{FALSE}} 557 clang_analyzer_eval(feof(F1)); // expected-warning {{TRUE}} 558 } 559 } 560 if (F0) 561 fclose(F0); 562 if (F1) 563 fclose(F1); 564 } 565 566 void error_indeterminate(void) { 567 FILE *F = fopen("file", "r+"); 568 if (!F) 569 return; 570 const char *Buf = "123456789"; 571 int rc = fseek(F, 0, SEEK_SET); 572 if (rc) { 573 if (feof(F)) { 574 fwrite(Buf, 1, 10, F); // no warning 575 } else if (ferror(F)) { 576 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 577 } else { 578 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 579 } 580 } 581 fclose(F); 582 } 583 584 void error_indeterminate_clearerr(void) { 585 FILE *F = fopen("file", "r+"); 586 if (!F) 587 return; 588 const char *Buf = "123456789"; 589 int rc = fseek(F, 0, SEEK_SET); 590 if (rc) { 591 if (feof(F)) { 592 clearerr(F); 593 fwrite(Buf, 1, 10, F); // no warning 594 } else if (ferror(F)) { 595 clearerr(F); 596 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 597 } else { 598 clearerr(F); 599 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}} 600 } 601 } 602 fclose(F); 603 } 604 605 void error_indeterminate_feof1(void) { 606 FILE *F = fopen("file", "r+"); 607 if (!F) 608 return; 609 char Buf[10]; 610 if (fread(Buf, 1, 10, F) < 10) { 611 if (feof(F)) { 612 // error is feof, should be non-indeterminate 613 fwrite("1", 1, 1, F); // no warning 614 } 615 } 616 fclose(F); 617 } 618 619 void error_indeterminate_feof2(void) { 620 FILE *F = fopen("file", "r+"); 621 if (!F) 622 return; 623 char Buf[10]; 624 if (fread(Buf, 1, 10, F) < 10) { 625 if (ferror(F) == 0) { 626 // error is feof, should be non-indeterminate 627 fwrite("1", 1, 1, F); // no warning 628 } 629 } 630 fclose(F); 631 } 632