xref: /llvm-project/clang/test/Analysis/errno.c (revision 72d3bf2b87ff7fab1a189d76f516bc03eac3271d)
1 // RUN: %clang_analyze_cc1 -verify %s \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-checker=apiModeling.Errno \
4 // RUN:   -analyzer-checker=debug.ExprInspection \
5 // RUN:   -analyzer-checker=debug.ErrnoTest \
6 // RUN:   -analyzer-checker=unix.Errno \
7 // RUN:   -DERRNO_VAR
8 
9 // RUN: %clang_analyze_cc1 -verify %s \
10 // RUN:   -analyzer-checker=core \
11 // RUN:   -analyzer-checker=apiModeling.Errno \
12 // RUN:   -analyzer-checker=debug.ExprInspection \
13 // RUN:   -analyzer-checker=debug.ErrnoTest \
14 // RUN:   -analyzer-checker=unix.Errno \
15 // RUN:   -DERRNO_FUNC
16 
17 #include "Inputs/system-header-simulator.h"
18 #ifdef ERRNO_VAR
19 #include "Inputs/errno_var.h"
20 #endif
21 #ifdef ERRNO_FUNC
22 #include "Inputs/errno_func.h"
23 #endif
24 
25 void clang_analyzer_eval(int);
26 void ErrnoTesterChecker_setErrno(int);
27 int ErrnoTesterChecker_getErrno();
28 int ErrnoTesterChecker_setErrnoIfError();
29 int ErrnoTesterChecker_setErrnoIfErrorRange();
30 int ErrnoTesterChecker_setErrnoCheckState();
31 
32 void something();
33 
test()34 void test() {
35   // Test if errno is initialized.
36   clang_analyzer_eval(errno == 0); // expected-warning{{TRUE}}
37 
38   ErrnoTesterChecker_setErrno(1);
39   // Test if errno was recognized and changed.
40   clang_analyzer_eval(errno == 1);                         // expected-warning{{TRUE}}
41   clang_analyzer_eval(ErrnoTesterChecker_getErrno() == 1); // expected-warning{{TRUE}}
42 
43   something();
44 
45   // Test if errno was invalidated.
46   clang_analyzer_eval(errno);                         // expected-warning{{UNKNOWN}}
47   clang_analyzer_eval(ErrnoTesterChecker_getErrno()); // expected-warning{{UNKNOWN}}
48 }
49 
testRange(int X)50 void testRange(int X) {
51   if (X > 0) {
52     ErrnoTesterChecker_setErrno(X);
53     clang_analyzer_eval(errno > 0); // expected-warning{{TRUE}}
54   }
55 }
56 
testIfError()57 void testIfError() {
58   if (ErrnoTesterChecker_setErrnoIfError())
59     clang_analyzer_eval(errno == 11); // expected-warning{{TRUE}}
60 }
61 
testIfErrorRange()62 void testIfErrorRange() {
63   if (ErrnoTesterChecker_setErrnoIfErrorRange()) {
64     clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
65     clang_analyzer_eval(errno == 1); // expected-warning{{FALSE}} expected-warning{{TRUE}}
66   }
67 }
68 
testErrnoCheck0()69 void testErrnoCheck0() {
70   // If the function returns a success result code, value of 'errno'
71   // is unspecified and it is unsafe to make any decision with it.
72   // The function did not promise to not change 'errno' if no failure happens.
73   int X = ErrnoTesterChecker_setErrnoCheckState();
74   if (X == 0) {
75     if (errno) { // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
76     }
77     if (errno) { // no warning for second time (analysis stops at the first warning)
78     }
79   }
80   X = ErrnoTesterChecker_setErrnoCheckState();
81   if (X == 0) {
82     if (errno) { // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
83     }
84     errno = 0;
85   }
86   X = ErrnoTesterChecker_setErrnoCheckState();
87   if (X == 0) {
88     errno = 0;
89     if (errno) { // no warning after overwritten 'errno'
90     }
91   }
92 }
93 
testErrnoCheck1()94 void testErrnoCheck1() {
95   // If the function returns error result code that is out-of-band (not a valid
96   // non-error return value) the value of 'errno' can be checked but it is not
97   // required to do so.
98   int X = ErrnoTesterChecker_setErrnoCheckState();
99   if (X == 1) {
100     if (errno) { // no warning
101     }
102   }
103   X = ErrnoTesterChecker_setErrnoCheckState();
104   if (X == 1) {
105     errno = 0; // no warning
106   }
107 }
108 
testErrnoCheck2()109 void testErrnoCheck2() {
110   // If the function returns an in-band error result the value of 'errno' is
111   // required to be checked to verify if error happened.
112   // The same applies to other functions that can indicate failure only by
113   // change of 'errno'.
114   int X = ErrnoTesterChecker_setErrnoCheckState();
115   if (X == 2) {
116     errno = 0; // expected-warning{{Value of 'errno' was not checked and is overwritten here [unix.Errno]}}
117     errno = 0;
118   }
119   X = ErrnoTesterChecker_setErrnoCheckState();
120   if (X == 2) {
121     errno = 0; // expected-warning{{Value of 'errno' was not checked and is overwritten here [unix.Errno]}}
122     if (errno) {
123     }
124   }
125 }
126 
testErrnoCheck3()127 void testErrnoCheck3() {
128   int X = ErrnoTesterChecker_setErrnoCheckState();
129   if (X == 2) {
130     if (errno) {
131     }
132     errno = 0; // no warning after 'errno' was read
133   }
134   X = ErrnoTesterChecker_setErrnoCheckState();
135   if (X == 2) {
136     int A = errno;
137     errno = 0; // no warning after 'errno' was read
138   }
139 }
140 
testErrnoCheckUndefinedLoad()141 void testErrnoCheckUndefinedLoad() {
142   int X = ErrnoTesterChecker_setErrnoCheckState();
143   if (X == 0) {
144     if (errno) { // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
145     }
146   }
147 }
148 
testErrnoNotCheckedAtSystemCall()149 void testErrnoNotCheckedAtSystemCall() {
150   int X = ErrnoTesterChecker_setErrnoCheckState();
151   if (X == 2) {
152     printf("%i", 1); // expected-warning{{Value of 'errno' was not checked and may be overwritten by function 'printf' [unix.Errno]}}
153     printf("%i", 1); // no warning ('printf' does not change errno state)
154   }
155 }
156 
testErrnoCheckStateInvalidate()157 void testErrnoCheckStateInvalidate() {
158   int X = ErrnoTesterChecker_setErrnoCheckState();
159   if (X == 0) {
160     something();
161     if (errno) { // no warning after an invalidating function call
162     }
163   }
164   X = ErrnoTesterChecker_setErrnoCheckState();
165   if (X == 0) {
166     printf("%i", 1);
167     if (errno) { // no warning after an invalidating standard function call
168     }
169   }
170 }
171 
testErrnoCheckStateInvalidate1()172 void testErrnoCheckStateInvalidate1() {
173   int X = ErrnoTesterChecker_setErrnoCheckState();
174   if (X == 2) {
175     clang_analyzer_eval(errno); // expected-warning{{TRUE}}
176     something();
177     clang_analyzer_eval(errno); // expected-warning{{UNKNOWN}}
178     errno = 0;                  // no warning after invalidation
179   }
180 }
181 
test_if_cond_in_expr()182 void test_if_cond_in_expr() {
183   ErrnoTesterChecker_setErrnoIfError();
184   if (errno + 10 > 2) {
185     // expected-warning@-1{{An undefined value may be read from 'errno'}}
186   }
187 }
188 
test_for_cond()189 void test_for_cond() {
190   ErrnoTesterChecker_setErrnoIfError();
191   for (; errno != 0;) {
192   // expected-warning@-1{{An undefined value may be read from 'errno'}}
193   }
194 }
195 
test_do_cond()196 void test_do_cond() {
197   ErrnoTesterChecker_setErrnoIfError();
198   do {
199   } while (errno != 0);
200   // expected-warning@-1{{An undefined value may be read from 'errno'}}
201 }
202 
test_while_cond()203 void test_while_cond() {
204   ErrnoTesterChecker_setErrnoIfError();
205   while (errno != 0) {
206   // expected-warning@-1{{An undefined value may be read from 'errno'}}
207   }
208 }
209 
test_switch_cond()210 void test_switch_cond() {
211   ErrnoTesterChecker_setErrnoIfError();
212   switch (errno) {}
213   // expected-warning@-1{{An undefined value may be read from 'errno'}}
214 }
215 
test_conditional_cond()216 void test_conditional_cond() {
217   ErrnoTesterChecker_setErrnoIfError();
218   int A = errno ? 1 : 2;
219   // expected-warning@-1{{An undefined value may be read from 'errno'}}
220 }
221 
test_binary_conditional_cond()222 void test_binary_conditional_cond() {
223   ErrnoTesterChecker_setErrnoIfError();
224   int A = errno ?: 2;
225   // expected-warning@-1{{An undefined value may be read from 'errno'}}
226 }
227 
test_errno_store_into_variable()228 void test_errno_store_into_variable() {
229   ErrnoTesterChecker_setErrnoIfError();
230   int a = errno; // AllowNonConditionErrnoRead is on by default, no warning
231 }
232 
test_errno_store_into_variable_in_expr()233 void test_errno_store_into_variable_in_expr() {
234   ErrnoTesterChecker_setErrnoIfError();
235   int a = errno > 1; // AllowNonConditionErrnoRead is on by default, no warning
236 }
237 
test_errno_return()238 int test_errno_return() {
239   ErrnoTesterChecker_setErrnoIfError();
240   return errno;
241 }
242 
test_errno_pointer1()243 void test_errno_pointer1() {
244   ErrnoTesterChecker_setErrnoIfError();
245   int *ErrnoP = &errno;
246   int A = errno ? 1 : 2;
247   // expected-warning@-1{{An undefined value may be read from 'errno'}}
248 }
249 
test_errno_pointer2()250 void test_errno_pointer2() {
251   ErrnoTesterChecker_setErrnoIfError();
252   int *ErrnoP = &errno;
253   int A = (*ErrnoP) ? 1 : 2;
254   // expected-warning@-1{{An undefined value may be read from 'errno'}}
255 }
256 
257 int f(int);
258 
test_errno_in_condition_in_function_call()259 void test_errno_in_condition_in_function_call() {
260   ErrnoTesterChecker_setErrnoIfError();
261   if (f(errno) != 0) {
262   }
263 }
264