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_dump(int);
11 void clang_analyzer_warnIfReached(void);
12 void StreamTesterChecker_make_feof_stream(FILE *);
13 void StreamTesterChecker_make_ferror_stream(FILE *);
15 void error_fopen(void) {
16 FILE *F
= fopen("file", "r");
19 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
20 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
24 void error_freopen(void) {
25 FILE *F
= fopen("file", "r");
28 F
= freopen(0, "w", F
);
31 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
32 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
36 void stream_error_feof(void) {
37 FILE *F
= fopen("file", "r");
40 StreamTesterChecker_make_feof_stream(F
);
41 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
42 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
44 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
45 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
49 void stream_error_ferror(void) {
50 FILE *F
= fopen("file", "r");
53 StreamTesterChecker_make_ferror_stream(F
);
54 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
55 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
57 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
58 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
62 void error_fread(void) {
67 int Ret
= fread(Buf
, 1, 10, F
);
69 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{FALSE}}
71 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{TRUE}}
73 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
74 fread(Buf
, 1, 10, F
); // expected-warning {{Read function called when stream is in EOF state}}
75 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
76 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
79 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
80 fread(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
84 Ret
= fread(Buf
, 1, 10, F
); // expected-warning {{Stream might be already closed}}
87 void error_fwrite(void) {
91 const char *Buf
= "123456789";
92 int Ret
= fwrite(Buf
, 1, 10, F
);
94 clang_analyzer_eval(feof(F
) || ferror(F
)); // expected-warning {{FALSE}}
96 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
97 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
98 fwrite(0, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
101 Ret
= fwrite(0, 1, 10, F
); // expected-warning {{Stream might be already closed}}
104 void freadwrite_zerosize(FILE *F
) {
106 Ret
= fwrite(0, 1, 0, F
);
107 clang_analyzer_dump(Ret
); // expected-warning {{0 }}
108 Ret
= fwrite(0, 0, 1, F
);
109 clang_analyzer_dump(Ret
); // expected-warning {{0 }}
110 Ret
= fread(0, 1, 0, F
);
111 clang_analyzer_dump(Ret
); // expected-warning {{0 }}
112 Ret
= fread(0, 0, 1, F
);
113 clang_analyzer_dump(Ret
); // expected-warning {{0 }}
116 void freadwrite_zerosize_eofstate(FILE *F
) {
119 fread(0, 1, 0, F
); // expected-warning {{Read function called when stream is in EOF state}}
120 fread(0, 0, 1, F
); // expected-warning {{Read function called when stream is in EOF state}}
123 void error_fread_fwrite_zerosize(void) {
124 FILE *F
= fopen("file", "r");
128 freadwrite_zerosize(F
);
129 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
130 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
132 StreamTesterChecker_make_ferror_stream(F
);
133 freadwrite_zerosize(F
);
134 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
135 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
137 StreamTesterChecker_make_feof_stream(F
);
138 freadwrite_zerosize_eofstate(F
);
139 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
140 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
145 void error_fseek(void) {
146 FILE *F
= fopen("file", "r");
149 int rc
= fseek(F
, 1, SEEK_SET
);
151 int IsFEof
= feof(F
), IsFError
= ferror(F
);
152 // Get feof or ferror or no error.
153 clang_analyzer_eval(IsFEof
|| IsFError
);
154 // expected-warning@-1 {{FALSE}}
155 // expected-warning@-2 {{TRUE}}
156 clang_analyzer_eval(IsFEof
&& IsFError
); // expected-warning {{FALSE}}
157 // Error flags should not change.
159 clang_analyzer_eval(feof(F
)); // expected-warning {{TRUE}}
161 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
163 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
165 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
167 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
168 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
169 // Error flags should not change.
170 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
171 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
176 void error_fseek_0(void) {
177 FILE *F
= fopen("file", "r");
180 int rc
= fseek(F
, 0, SEEK_SET
);
182 int IsFEof
= feof(F
), IsFError
= ferror(F
);
183 // Get ferror or no error, but not feof.
184 clang_analyzer_eval(IsFError
);
185 // expected-warning@-1 {{FALSE}}
186 // expected-warning@-2 {{TRUE}}
187 clang_analyzer_eval(IsFEof
);
188 // expected-warning@-1 {{FALSE}}
189 // Error flags should not change.
190 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
192 clang_analyzer_eval(ferror(F
)); // expected-warning {{TRUE}}
194 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
196 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
197 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
198 // Error flags should not change.
199 clang_analyzer_eval(feof(F
)); // expected-warning {{FALSE}}
200 clang_analyzer_eval(ferror(F
)); // expected-warning {{FALSE}}
205 void error_indeterminate(void) {
206 FILE *F
= fopen("file", "r+");
209 const char *Buf
= "123456789";
210 int rc
= fseek(F
, 0, SEEK_SET
);
213 fwrite(Buf
, 1, 10, F
); // no warning
214 } else if (ferror(F
)) {
215 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
217 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
223 void error_indeterminate_clearerr(void) {
224 FILE *F
= fopen("file", "r+");
227 const char *Buf
= "123456789";
228 int rc
= fseek(F
, 0, SEEK_SET
);
232 fwrite(Buf
, 1, 10, F
); // no warning
233 } else if (ferror(F
)) {
235 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
238 fwrite(Buf
, 1, 10, F
); // expected-warning {{might be 'indeterminate'}}
244 void error_indeterminate_feof1(void) {
245 FILE *F
= fopen("file", "r+");
249 if (fread(Buf
, 1, 10, F
) < 10) {
251 // error is feof, should be non-indeterminate
252 fwrite("1", 1, 1, F
); // no warning
258 void error_indeterminate_feof2(void) {
259 FILE *F
= fopen("file", "r+");
263 if (fread(Buf
, 1, 10, F
) < 10) {
264 if (ferror(F
) == 0) {
265 // error is feof, should be non-indeterminate
266 fwrite("1", 1, 1, F
); // no warning