1// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s
2
3typedef __typeof__(sizeof(int)) size_t;
4typedef struct _IO_FILE FILE;
5#define SEEK_SET	0	/* Seek from beginning of file.  */
6#define SEEK_CUR	1	/* Seek from current position.  */
7#define SEEK_END	2	/* Seek from end of file.  */
8extern FILE *fopen(const char *path, const char *mode);
9extern FILE *tmpfile(void);
10extern int fclose(FILE *fp);
11extern size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
12extern int fseek (FILE *__stream, long int __off, int __whence);
13extern long int ftell (FILE *__stream);
14extern void rewind (FILE *__stream);
15
16void f1(void) {
17  FILE *p = fopen("foo", "r");
18  char buf[1024];
19  fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL}}
20  fclose(p);
21}
22
23void f2(void) {
24  FILE *p = fopen("foo", "r");
25  fseek(p, 1, SEEK_SET); // expected-warning {{Stream pointer might be NULL}}
26  fclose(p);
27}
28
29void f3(void) {
30  FILE *p = fopen("foo", "r");
31  ftell(p); // expected-warning {{Stream pointer might be NULL}}
32  fclose(p);
33}
34
35void f4(void) {
36  FILE *p = fopen("foo", "r");
37  rewind(p); // expected-warning {{Stream pointer might be NULL}}
38  fclose(p);
39}
40
41void f5(void) {
42  FILE *p = fopen("foo", "r");
43  if (!p)
44    return;
45  fseek(p, 1, SEEK_SET); // no-warning
46  fseek(p, 1, 3); // expected-warning {{The whence argument to fseek() should be SEEK_SET, SEEK_END, or SEEK_CUR}}
47  fclose(p);
48}
49
50void f6(void) {
51  FILE *p = fopen("foo", "r");
52  fclose(p);
53  fclose(p); // expected-warning {{Try to close a file Descriptor already closed. Cause undefined behaviour}}
54}
55
56void f7(void) {
57  FILE *p = tmpfile();
58  ftell(p); // expected-warning {{Stream pointer might be NULL}}
59  fclose(p);
60}
61
62void f8(int c) {
63  FILE *p = fopen("foo.c", "r");
64  if(c)
65    return; // expected-warning {{Opened File never closed. Potential Resource leak}}
66  fclose(p);
67}
68
69FILE *f9(void) {
70  FILE *p = fopen("foo.c", "r");
71  if (p)
72    return p; // no-warning
73  else
74    return 0;
75}
76
77void pr7831(FILE *fp) {
78  fclose(fp); // no-warning
79}
80
81// PR 8081 - null pointer crash when 'whence' is not an integer constant
82void pr8081(FILE *stream, long offset, int whence) {
83  fseek(stream, offset, whence);
84}
85
86