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
7 #include "Inputs/system-header-simulator.h"
9 void clang_analyzer_eval(int);
10 void clang_analyzer_warnIfReached(void);
11 void StreamTesterChecker_make_feof_stream(FILE *);
12 void StreamTesterChecker_make_ferror_stream(FILE *);
14 void error_fopen(void) {
15 FILE *F
= fopen("file", "r");
18 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
19 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
23 void error_freopen(void) {
24 FILE *F
= fopen("file", "r");
27 F
= freopen(0, "w", F
);
30 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
31 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
35 void stream_error_feof(void) {
36 FILE *F
= fopen("file", "r");
39 StreamTesterChecker_make_feof_stream(F
);
40 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
41 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
43 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
44 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
48 void stream_error_ferror(void) {
49 FILE *F
= fopen("file", "r");
52 StreamTesterChecker_make_ferror_stream(F
);
53 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
54 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
56 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
57 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
61 void error_fread(void) {
66 int Ret
= fread(Buf
, 1, 10, F
);
68 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{FALSE}}
70 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{TRUE}}
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}}
78 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
79 fread(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
83 Ret
= fread(Buf
, 1, 10, F
); // expected-warning {{Stream might be already closed}}
86 void error_fwrite(void) {
90 const char *Buf
= "123456789";
91 int Ret
= fwrite(Buf
, 1, 10, F
);
93 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{FALSE}}
95 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
96 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
97 fwrite(0, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
100 Ret
= fwrite(0, 1, 10, F
); // expected-warning {{Stream might be already closed}}
103 void freadwrite_zerosize(FILE *F
) {
110 void freadwrite_zerosize_eofstate(FILE *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}}
117 void error_fread_fwrite_zerosize(void) {
118 FILE *F
= fopen("file", "r");
122 freadwrite_zerosize(F
);
123 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
124 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
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}}
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}}
139 void error_fseek(void) {
140 FILE *F
= fopen("file", "r");
143 int rc
= fseek(F
, 0, SEEK_SET
);
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.
153 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
155 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
157 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
159 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
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}}
170 void error_indeterminate(void) {
171 FILE *F
= fopen("file", "r+");
174 const char *Buf
= "123456789";
175 int rc
= fseek(F
, 0, SEEK_SET
);
178 fwrite(Buf
, 1, 10, F
); // no warning
179 } else if (ferror(F
)) {
180 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
182 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
188 void error_indeterminate_clearerr(void) {
189 FILE *F
= fopen("file", "r+");
192 const char *Buf
= "123456789";
193 int rc
= fseek(F
, 0, SEEK_SET
);
197 fwrite(Buf
, 1, 10, F
); // no warning
198 } else if (ferror(F
)) {
200 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
203 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
209 void error_indeterminate_feof1(void) {
210 FILE *F
= fopen("file", "r+");
214 if (fread(Buf
, 1, 10, F
) < 10) {
216 // error is feof, should be non-indeterminate
217 fwrite("1", 1, 1, F
); // no warning
223 void error_indeterminate_feof2(void) {
224 FILE *F
= fopen("file", "r+");
228 if (fread(Buf
, 1, 10, F
) < 10) {
229 if (ferror(F
) == 0) {
230 // error is feof, should be non-indeterminate
231 fwrite("1", 1, 1, F
); // no warning