1 // RUN: %clang_analyze_cc1 -verify %s \ 2 // RUN: -analyzer-checker=core \ 3 // RUN: -analyzer-checker=alpha.unix.Stream \ 4 // RUN: -analyzer-checker=debug.StreamTester \ 5 // RUN: -analyzer-checker=debug.ExprInspection 6 7 #include "Inputs/system-header-simulator.h" 8 9 void clang_analyzer_eval(int); 10 void clang_analyzer_warnIfReached(); 11 void StreamTesterChecker_make_feof_stream(FILE *); 12 void StreamTesterChecker_make_ferror_stream(FILE *); 13 14 void error_fopen() { 15 FILE *F = fopen("file", "r"); 16 if (!F) 17 return; 18 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 19 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 20 fclose(F); 21 } 22 23 void error_freopen() { 24 FILE *F = fopen("file", "r"); 25 if (!F) 26 return; 27 F = freopen(0, "w", F); 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 stream_error_feof() { 36 FILE *F = fopen("file", "r"); 37 if (!F) 38 return; 39 StreamTesterChecker_make_feof_stream(F); 40 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 41 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 42 clearerr(F); 43 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 44 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 45 fclose(F); 46 } 47 48 void stream_error_ferror() { 49 FILE *F = fopen("file", "r"); 50 if (!F) 51 return; 52 StreamTesterChecker_make_ferror_stream(F); 53 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 54 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 55 clearerr(F); 56 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 57 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 58 fclose(F); 59 } 60 61 void error_fread() { 62 FILE *F = tmpfile(); 63 if (!F) 64 return; 65 char Buf[10]; 66 int Ret = fread(Buf, 1, 10, F); 67 if (Ret == 10) { 68 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 69 } else { 70 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}} 71 if (feof(F)) { 72 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 73 fread(Buf, 1, 10, F); // expected-warning {{Read function called when stream is in EOF state}} 74 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 75 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 76 } 77 if (ferror(F)) { 78 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} 79 fread(Buf, 1, 10, F); // no warning 80 } 81 } 82 fclose(F); 83 Ret = fread(Buf, 1, 10, F); // expected-warning {{Stream might be already closed}} 84 } 85 86 void error_fwrite() { 87 FILE *F = tmpfile(); 88 if (!F) 89 return; 90 const char *Buf = "123456789"; 91 int Ret = fwrite(Buf, 1, 10, F); 92 if (Ret == 10) { 93 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}} 94 } else { 95 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 96 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 97 fwrite(0, 1, 10, F); // no warning 98 } 99 fclose(F); 100 Ret = fwrite(0, 1, 10, F); // expected-warning {{Stream might be already closed}} 101 } 102 103 void freadwrite_zerosize(FILE *F) { 104 fwrite(0, 1, 0, F); 105 fwrite(0, 0, 1, F); 106 fread(0, 1, 0, F); 107 fread(0, 0, 1, F); 108 } 109 110 void freadwrite_zerosize_eofstate(FILE *F) { 111 fwrite(0, 1, 0, F); 112 fwrite(0, 0, 1, F); 113 fread(0, 1, 0, F); // expected-warning {{Read function called when stream is in EOF state}} 114 fread(0, 0, 1, F); // expected-warning {{Read function called when stream is in EOF state}} 115 } 116 117 void error_fread_fwrite_zerosize() { 118 FILE *F = fopen("file", "r"); 119 if (!F) 120 return; 121 122 freadwrite_zerosize(F); 123 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 124 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 125 126 StreamTesterChecker_make_ferror_stream(F); 127 freadwrite_zerosize(F); 128 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 129 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 130 131 StreamTesterChecker_make_feof_stream(F); 132 freadwrite_zerosize_eofstate(F); 133 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 134 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 135 136 fclose(F); 137 } 138 139 void error_fseek() { 140 FILE *F = fopen("file", "r"); 141 if (!F) 142 return; 143 int rc = fseek(F, 0, SEEK_SET); 144 if (rc) { 145 int IsFEof = feof(F), IsFError = ferror(F); 146 // Get feof or ferror or no error. 147 clang_analyzer_eval(IsFEof || IsFError); 148 // expected-warning@-1 {{FALSE}} 149 // expected-warning@-2 {{TRUE}} 150 clang_analyzer_eval(IsFEof && IsFError); // expected-warning {{FALSE}} 151 // Error flags should not change. 152 if (IsFEof) 153 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} 154 else 155 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 156 if (IsFError) 157 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} 158 else 159 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 160 } else { 161 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 162 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 163 // Error flags should not change. 164 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} 165 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} 166 } 167 fclose(F); 168 } 169