| // RUN: %clang_analyze_cc1 -verify %s \ |
| // RUN: -analyzer-checker=core \ |
| // RUN: -analyzer-checker=unix.Errno \ |
| // RUN: -analyzer-checker=unix.Stream \ |
| // RUN: -analyzer-checker=unix.StdCLibraryFunctions \ |
| // RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true \ |
| // RUN: -analyzer-checker=debug.ExprInspection |
| |
| // enable only StdCLibraryFunctions checker |
| // RUN: %clang_analyze_cc1 -verify %s \ |
| // RUN: -analyzer-checker=core \ |
| // RUN: -analyzer-checker=unix.Errno \ |
| // RUN: -analyzer-checker=unix.StdCLibraryFunctions \ |
| // RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true \ |
| // RUN: -analyzer-checker=debug.ExprInspection |
| |
| #include "Inputs/system-header-simulator.h" |
| #include "Inputs/errno_var.h" |
| |
| void clang_analyzer_eval(int); |
| |
| const char *WBuf = "123456789"; |
| char RBuf[10]; |
| |
| void test_freopen(FILE *F) { |
| F = freopen("xxx", "w", F); |
| if (F) { |
| if (errno) {} // expected-warning{{undefined}} |
| } else { |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| } |
| |
| void test_fread(FILE *F) { |
| size_t Ret = fread(RBuf, 1, 10, F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == 10) { |
| if (errno) {} // expected-warning{{undefined}} |
| } else { |
| clang_analyzer_eval(Ret < 10); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_fwrite(FILE *F) { |
| size_t Ret = fwrite(WBuf, 1, 10, F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == 10) { |
| if (errno) {} // expected-warning{{undefined}} |
| } else { |
| clang_analyzer_eval(Ret < 10); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_fgetc(FILE *F) { |
| int Ret = fgetc(F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret != EOF) { |
| if (errno) {} // expected-warning {{undefined}} |
| } else { |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| // expected-warning@-1 {{FALSE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_fputc(FILE *F) { |
| int Ret = fputc('a', F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret != EOF) { |
| clang_analyzer_eval(Ret == 'a'); // expected-warning {{TRUE}} |
| if (errno) {} // expected-warning {{undefined}} |
| } else { |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_fgets(char *Buf, int N, FILE *F) { |
| char *Ret = fgets(Buf, N, F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| clang_analyzer_eval(Buf != NULL); // expected-warning {{TRUE}} |
| clang_analyzer_eval(N >= 0); // expected-warning {{TRUE}} |
| if (Ret == Buf) { |
| if (errno) {} // expected-warning {{undefined}} |
| } else { |
| clang_analyzer_eval(Ret == 0); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| // expected-warning@-1 {{FALSE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| |
| char Buf1[10]; |
| Ret = fgets(Buf1, 11, F); // expected-warning {{The 1st argument to 'fgets' is a buffer with size 10}} |
| } |
| |
| void test_fgets_bufsize(FILE *F) { |
| char Buf[10]; |
| fgets(Buf, 11, F); // expected-warning {{The 1st argument to 'fgets' is a buffer with size 10}} |
| } |
| |
| void test_fputs(char *Buf, FILE *F) { |
| int Ret = fputs(Buf, F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| clang_analyzer_eval(Buf != NULL); // expected-warning {{TRUE}} |
| if (Ret >= 0) { |
| if (errno) {} // expected-warning {{undefined}} |
| } else { |
| clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_ungetc(FILE *F) { |
| int Ret = ungetc('X', F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == 'X') { |
| if (errno) {} // expected-warning {{undefined}} |
| } else { |
| clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_ungetc_EOF(FILE *F, int C) { |
| int Ret = ungetc(EOF, F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| Ret = ungetc(C, F); |
| if (Ret == EOF) { |
| clang_analyzer_eval(C == EOF); // expected-warning {{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| } |
| |
| void test_fclose(FILE *F) { |
| int Ret = fclose(F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == 0) { |
| if (errno) {} // expected-warning{{undefined}} |
| } else { |
| clang_analyzer_eval(Ret == EOF); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_fseek(FILE *F) { |
| int Ret = fseek(F, SEEK_SET, 1); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == 0) { |
| if (errno) {} // expected-warning{{undefined}} |
| } else { |
| clang_analyzer_eval(Ret == -1); // expected-warning {{TRUE}} |
| clang_analyzer_eval(errno != 0); // expected-warning {{TRUE}} |
| } |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void check_fgetpos(FILE *F) { |
| errno = 0; |
| fpos_t Pos; |
| int Ret = fgetpos(F, &Pos); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret) |
| clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} |
| else |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void check_fsetpos(FILE *F) { |
| errno = 0; |
| fpos_t Pos; |
| int Ret = fsetpos(F, &Pos); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret) |
| clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} |
| else |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void check_ftell(FILE *F) { |
| errno = 0; |
| long Ret = ftell(F); |
| clang_analyzer_eval(F != NULL); // expected-warning {{TRUE}} |
| if (Ret == -1) { |
| clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} |
| } else { |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| clang_analyzer_eval(Ret >= 0); // expected-warning{{TRUE}} |
| } |
| if (errno) {} // no-warning |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void test_rewind(FILE *F) { |
| errno = 0; |
| rewind(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| rewind(F); |
| } |
| |
| void test_fflush(FILE *F) { |
| errno = 0; |
| int Ret = fflush(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| if (Ret == EOF) { |
| clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}} |
| } else { |
| clang_analyzer_eval(Ret == 0); // expected-warning{{TRUE}} |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| } |
| |
| void test_feof(FILE *F) { |
| errno = 0; |
| feof(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| |
| void test_ferror(FILE *F) { |
| errno = 0; |
| ferror(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| |
| void test_clearerr(FILE *F) { |
| errno = 0; |
| clearerr(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| |
| void test_fileno(FILE *F) { |
| errno = 0; |
| int A = fileno(F); |
| clang_analyzer_eval(F != NULL); // expected-warning{{TRUE}} |
| clang_analyzer_eval(A >= 0); // expected-warning{{TRUE}} |
| if (errno) {} // no-warning |
| clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}} |
| // expected-warning@-1{{FALSE}} |
| } |
| |
| void freadwrite_zerosize(FILE *F) { |
| fwrite(WBuf, 1, 0, F); |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| fwrite(WBuf, 0, 1, F); |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| fread(RBuf, 1, 0, F); |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| fread(RBuf, 0, 1, F); |
| clang_analyzer_eval(feof(F)); // expected-warning {{UNKNOWN}} |
| clang_analyzer_eval(ferror(F)); // expected-warning {{UNKNOWN}} |
| } |
| |
| void freadwrite_zerosize_errno(FILE *F, int A) { |
| switch (A) { |
| case 1: |
| fwrite(WBuf, 1, 0, F); |
| if (errno) {} // expected-warning{{undefined}} |
| break; |
| case 2: |
| fwrite(WBuf, 0, 1, F); |
| if (errno) {} // expected-warning{{undefined}} |
| break; |
| case 3: |
| fread(RBuf, 1, 0, F); |
| if (errno) {} // expected-warning{{undefined}} |
| break; |
| case 4: |
| fread(RBuf, 0, 1, F); |
| if (errno) {} // expected-warning{{undefined}} |
| break; |
| } |
| } |