Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / stream-error.c
blob3c00e59bb6bd19d3408076fbebae8d978304b41d
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");
17 if (!F)
18 return;
19 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
20 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
21 fclose(F);
24 void error_freopen(void) {
25 FILE *F = fopen("file", "r");
26 if (!F)
27 return;
28 F = freopen(0, "w", F);
29 if (!F)
30 return;
31 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
32 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
33 fclose(F);
36 void stream_error_feof(void) {
37 FILE *F = fopen("file", "r");
38 if (!F)
39 return;
40 StreamTesterChecker_make_feof_stream(F);
41 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}}
42 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
43 clearerr(F);
44 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
45 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
46 fclose(F);
49 void stream_error_ferror(void) {
50 FILE *F = fopen("file", "r");
51 if (!F)
52 return;
53 StreamTesterChecker_make_ferror_stream(F);
54 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
55 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
56 clearerr(F);
57 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
58 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
59 fclose(F);
62 void error_fread(void) {
63 FILE *F = tmpfile();
64 if (!F)
65 return;
66 char Buf[10];
67 int Ret = fread(Buf, 1, 10, F);
68 if (Ret == 10) {
69 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}}
70 } else {
71 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{TRUE}}
72 if (feof(F)) {
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}}
78 if (ferror(F)) {
79 clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
80 fread(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}}
83 fclose(F);
84 Ret = fread(Buf, 1, 10, F); // expected-warning {{Stream might be already closed}}
87 void error_fwrite(void) {
88 FILE *F = tmpfile();
89 if (!F)
90 return;
91 const char *Buf = "123456789";
92 int Ret = fwrite(Buf, 1, 10, F);
93 if (Ret == 10) {
94 clang_analyzer_eval(feof(F) || ferror(F)); // expected-warning {{FALSE}}
95 } else {
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'}}
100 fclose(F);
101 Ret = fwrite(0, 1, 10, F); // expected-warning {{Stream might be already closed}}
104 void freadwrite_zerosize(FILE *F) {
105 size_t Ret;
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) {
117 fwrite(0, 1, 0, F);
118 fwrite(0, 0, 1, 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");
125 if (!F)
126 return;
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}}
142 fclose(F);
145 void error_fseek(void) {
146 FILE *F = fopen("file", "r");
147 if (!F)
148 return;
149 int rc = fseek(F, 1, SEEK_SET);
150 if (rc) {
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.
158 if (IsFEof)
159 clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}}
160 else
161 clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}}
162 if (IsFError)
163 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
164 else
165 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
166 } else {
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}}
173 fclose(F);
176 void error_fseek_0(void) {
177 FILE *F = fopen("file", "r");
178 if (!F)
179 return;
180 int rc = fseek(F, 0, SEEK_SET);
181 if (rc) {
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}}
191 if (IsFError)
192 clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}}
193 else
194 clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}}
195 } else {
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}}
202 fclose(F);
205 void error_indeterminate(void) {
206 FILE *F = fopen("file", "r+");
207 if (!F)
208 return;
209 const char *Buf = "123456789";
210 int rc = fseek(F, 0, SEEK_SET);
211 if (rc) {
212 if (feof(F)) {
213 fwrite(Buf, 1, 10, F); // no warning
214 } else if (ferror(F)) {
215 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}}
216 } else {
217 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}}
220 fclose(F);
223 void error_indeterminate_clearerr(void) {
224 FILE *F = fopen("file", "r+");
225 if (!F)
226 return;
227 const char *Buf = "123456789";
228 int rc = fseek(F, 0, SEEK_SET);
229 if (rc) {
230 if (feof(F)) {
231 clearerr(F);
232 fwrite(Buf, 1, 10, F); // no warning
233 } else if (ferror(F)) {
234 clearerr(F);
235 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}}
236 } else {
237 clearerr(F);
238 fwrite(Buf, 1, 10, F); // expected-warning {{might be 'indeterminate'}}
241 fclose(F);
244 void error_indeterminate_feof1(void) {
245 FILE *F = fopen("file", "r+");
246 if (!F)
247 return;
248 char Buf[10];
249 if (fread(Buf, 1, 10, F) < 10) {
250 if (feof(F)) {
251 // error is feof, should be non-indeterminate
252 fwrite("1", 1, 1, F); // no warning
255 fclose(F);
258 void error_indeterminate_feof2(void) {
259 FILE *F = fopen("file", "r+");
260 if (!F)
261 return;
262 char Buf[10];
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
269 fclose(F);