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()34void 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)50void testRange(int X) { 51 if (X > 0) { 52 ErrnoTesterChecker_setErrno(X); 53 clang_analyzer_eval(errno > 0); // expected-warning{{TRUE}} 54 } 55 } 56 testIfError()57void testIfError() { 58 if (ErrnoTesterChecker_setErrnoIfError()) 59 clang_analyzer_eval(errno == 11); // expected-warning{{TRUE}} 60 } 61 testIfErrorRange()62void 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()69void 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()94void 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()109void 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()127void 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()141void 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()149void 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()157void 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()172void 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()182void 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()189void 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()196void 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()203void 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()210void 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()216void 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()222void 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()228void 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()233void 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()238int test_errno_return() { 239 ErrnoTesterChecker_setErrnoIfError(); 240 return errno; 241 } 242 test_errno_pointer1()243void 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()250void 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()259void test_errno_in_condition_in_function_call() { 260 ErrnoTesterChecker_setErrnoIfError(); 261 if (f(errno) != 0) { 262 } 263 } 264