xref: /llvm-project/clang/test/Analysis/stream-errno-note.c (revision 09f160c6298255f520b379b88161fbd1c365b308)
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core \
2 // RUN:   -analyzer-checker=unix.Stream \
3 // RUN:   -analyzer-config unix.Stream:Pedantic=true \
4 // RUN:   -analyzer-checker=unix.Errno \
5 // RUN:   -analyzer-checker=unix.StdCLibraryFunctions \
6 // RUN:   -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true \
7 // RUN:   -analyzer-output text -verify %s
8 
9 #include "Inputs/system-header-simulator.h"
10 #include "Inputs/errno_func.h"
11 
check_fopen(void)12 void check_fopen(void) {
13   FILE *F = fopen("xxx", "r");
14   // expected-note@-1{{Assuming that 'fopen' is successful; 'errno' becomes undefined after the call}}
15   // expected-note@+2{{'F' is non-null}}
16   // expected-note@+1{{Taking false branch}}
17   if (!F)
18     return;
19   if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
20   // expected-note@-1{{An undefined value may be read from 'errno'}}
21   fclose(F);
22 }
23 
check_tmpfile(void)24 void check_tmpfile(void) {
25   FILE *F = tmpfile();
26   // expected-note@-1{{Assuming that 'tmpfile' is successful; 'errno' becomes undefined after the call}}
27   // expected-note@+2{{'F' is non-null}}
28   // expected-note@+1{{Taking false branch}}
29   if (!F)
30     return;
31   if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
32   // expected-note@-1{{An undefined value may be read from 'errno'}}
33   fclose(F);
34 }
35 
check_freopen(void)36 void check_freopen(void) {
37   FILE *F = tmpfile();
38   // expected-note@+2{{'F' is non-null}}
39   // expected-note@+1{{Taking false branch}}
40   if (!F)
41     return;
42   F = freopen("xxx", "w", F);
43   // expected-note@-1{{Assuming that 'freopen' is successful; 'errno' becomes undefined after the call}}
44   // expected-note@+2{{'F' is non-null}}
45   // expected-note@+1{{Taking false branch}}
46   if (!F)
47     return;
48   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
49   // expected-note@-1{{An undefined value may be read from 'errno'}}
50   fclose(F);
51 }
52 
check_fclose(void)53 void check_fclose(void) {
54   FILE *F = tmpfile();
55   // expected-note@+2{{'F' is non-null}}
56   // expected-note@+1{{Taking false branch}}
57   if (!F)
58     return;
59   (void)fclose(F);
60   // expected-note@-1{{Assuming that 'fclose' is successful; 'errno' becomes undefined after the call}}
61   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
62   // expected-note@-1{{An undefined value may be read from 'errno'}}
63 }
64 
check_fread(void)65 void check_fread(void) {
66   char Buf[10];
67   FILE *F = tmpfile();
68   // expected-note@+2{{'F' is non-null}}
69   // expected-note@+1{{Taking false branch}}
70   if (!F)
71     return;
72   (void)fread(Buf, 1, 10, F);
73   // expected-note@-1{{Assuming that 'fread' is successful; 'errno' becomes undefined after the call}}
74   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
75   // expected-note@-1{{An undefined value may be read from 'errno'}}
76   (void)fclose(F);
77 }
78 
check_fread_size0(void)79 void check_fread_size0(void) {
80   char Buf[10];
81   FILE *F = tmpfile();
82   // expected-note@+2{{'F' is non-null}}
83   // expected-note@+1{{Taking false branch}}
84   if (!F)
85     return;
86   fread(Buf, 0, 1, F);
87   // expected-note@-1{{Assuming that argument 'size' to 'fread' is 0; 'errno' becomes undefined after the call}}
88   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
89   // expected-note@-1{{An undefined value may be read from 'errno'}}
90 }
91 
check_fread_nmemb0(void)92 void check_fread_nmemb0(void) {
93   char Buf[10];
94   FILE *F = tmpfile();
95   // expected-note@+2{{'F' is non-null}}
96   // expected-note@+1{{Taking false branch}}
97   if (!F)
98     return;
99   fread(Buf, 1, 0, F);
100   // expected-note@-1{{Assuming that 'fread' is successful; 'errno' becomes undefined after the call}}
101   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
102   // expected-note@-1{{An undefined value may be read from 'errno'}}
103 }
104 
check_fwrite(void)105 void check_fwrite(void) {
106   char Buf[] = "0123456789";
107   FILE *F = tmpfile();
108   // expected-note@+2{{'F' is non-null}}
109   // expected-note@+1{{Taking false branch}}
110   if (!F)
111     return;
112   int R = fwrite(Buf, 1, 10, F);
113   // expected-note@-1{{Assuming that 'fwrite' is successful; 'errno' becomes undefined after the call}}
114   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
115   // expected-note@-1{{An undefined value may be read from 'errno'}}
116   (void)fclose(F);
117 }
118 
check_fseek(void)119 void check_fseek(void) {
120   FILE *F = tmpfile();
121   // expected-note@+2{{'F' is non-null}}
122   // expected-note@+1{{Taking false branch}}
123   if (!F)
124     return;
125   (void)fseek(F, 11, SEEK_SET);
126   // expected-note@-1{{Assuming that 'fseek' is successful; 'errno' becomes undefined after the call}}
127   if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
128   // expected-note@-1{{An undefined value may be read from 'errno'}}
129   (void)fclose(F);
130 }
131 
check_rewind_errnocheck(void)132 void check_rewind_errnocheck(void) {
133   FILE *F = tmpfile();
134   // expected-note@+2{{'F' is non-null}}
135   // expected-note@+1{{Taking false branch}}
136   if (!F)
137     return;
138   errno = 0;
139   rewind(F); // expected-note{{After calling 'rewind' reading 'errno' is required to find out if the call has failed}}
140   fclose(F); // expected-warning{{Value of 'errno' was not checked and may be overwritten by function 'fclose' [unix.Errno]}}
141   // expected-note@-1{{Value of 'errno' was not checked and may be overwritten by function 'fclose'}}
142 }
143 
check_fileno(void)144 void check_fileno(void) {
145   // nothing to check: checker assumes that 'fileno' is always successful
146   // (and does not change 'errno')
147 }
148 
check_fwrite_zeroarg(size_t Siz)149 void check_fwrite_zeroarg(size_t Siz) {
150   char Buf[] = "0123456789";
151   FILE *F = tmpfile();
152   // expected-note@+2{{'F' is non-null}}
153   // expected-note@+1{{Taking false branch}}
154   if (!F)
155     return;
156   errno = 0;
157   int R = fwrite(Buf, Siz, 1, F);
158   // expected-note@-1{{Assuming that argument 'size' to 'fwrite' is 0; 'errno' becomes undefined after the call}}
159   // expected-note@+2{{'R' is <= 0}}
160   // expected-note@+1{{Taking true branch}}
161   if (R <= 0) {
162     if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
163     // expected-note@-1{{An undefined value may be read from 'errno'}}
164   }
165   (void)fclose(F);
166 }
167