1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream -verify %s
3 #include "Inputs/system-header-simulator.h"
6 FILE *p
= fopen("foo", "r");
9 fseek(p
, 1, SEEK_SET
); // no-warning
10 fseek(p
, 1, 3); // expected-warning {{The whence argument to fseek() should be SEEK_SET, SEEK_END, or SEEK_CUR}}
14 void f_double_close(void) {
15 FILE *p
= fopen("foo", "r");
19 fclose(p
); // expected-warning {{Stream might be already closed}}
22 void f_double_close_alias(void) {
23 FILE *p1
= fopen("foo", "r");
28 fclose(p2
); // expected-warning {{Stream might be already closed}}
31 void f_use_after_close(void) {
32 FILE *p
= fopen("foo", "r");
36 clearerr(p
); // expected-warning {{Stream might be already closed}}
39 void f_open_after_close(void) {
40 FILE *p
= fopen("foo", "r");
44 p
= fopen("foo", "r");
50 void f_reopen_after_close(void) {
51 FILE *p
= fopen("foo", "r");
55 // Allow reopen after close.
56 p
= freopen("foo", "w", p
);
63 FILE *p
= fopen("foo.c", "r");
67 return; // expected-warning {{Opened stream never closed. Potential resource leak}}
71 FILE *f_null_checked(void) {
72 FILE *p
= fopen("foo.c", "r");
74 return p
; // no-warning
79 void pr7831(FILE *fp
) {
80 fclose(fp
); // no-warning
83 // PR 8081 - null pointer crash when 'whence' is not an integer constant
84 void pr8081(FILE *stream
, long offset
, int whence
) {
85 fseek(stream
, offset
, whence
);
88 void check_freopen_1(void) {
89 FILE *f1
= freopen("foo.c", "r", (FILE *)0); // Not reported by the stream checker.
90 f1
= freopen(0, "w", (FILE *)0x123456); // Do not report this as error.
93 void check_freopen_2(void) {
94 FILE *f1
= fopen("foo.c", "r");
96 FILE *f2
= freopen(0, "w", f1
);
98 // Check if f1 and f2 point to the same stream.
100 fclose(f2
); // expected-warning {{Stream might be already closed.}}
103 // f1 is non-NULL but points to a possibly invalid stream.
104 rewind(f1
); // expected-warning {{Stream might be invalid}}
105 // f2 is NULL but the previous error stops the checker.
111 void check_freopen_3(void) {
112 FILE *f1
= fopen("foo.c", "r");
114 // Unchecked result of freopen.
115 // The f1 may be invalid after this call.
117 rewind(f1
); // expected-warning {{Stream might be invalid}}
122 extern FILE *GlobalF
;
123 extern void takeFile(FILE *);
125 void check_escape1(void) {
129 fwrite("1", 1, 1, F
); // may fail
131 fwrite("1", 1, 1, F
); // no warning
134 void check_escape2(void) {
138 fwrite("1", 1, 1, F
); // may fail
140 fwrite("1", 1, 1, F
); // no warning
143 void check_escape3(void) {
148 F
= freopen(0, "w", F
);
151 fwrite("1", 1, 1, F
); // may fail
152 fwrite("1", 1, 1, F
); // no warning
155 void check_escape4(void) {
159 fwrite("1", 1, 1, F
); // may fail
161 // no escape at (non-StreamChecker-handled) system call
162 // FIXME: all such calls should be handled by the checker
165 fwrite("1", 1, 1, F
); // expected-warning {{might be 'indeterminate'}}
170 _Noreturn
void handle_error(void);
172 void check_leak_noreturn_1(void) {
173 FILE *F1
= tmpfile();
177 handle_error(); // no warning
180 } // expected-warning {{Opened stream never closed. Potential resource leak}}
182 // Check that "location uniqueing" works.
183 // This results in reporting only one occurence of resource leak for a stream.
184 void check_leak_noreturn_2(void) {
185 FILE *F1
= tmpfile();
189 return; // no warning
192 } // expected-warning {{Opened stream never closed. Potential resource leak}}
193 // FIXME: This warning should be placed at the `return` above.
194 // See https://reviews.llvm.org/D83120 about details.