264 lines · c
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_VAR8 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_FUNC16 17#include "Inputs/system-header-simulator.h"18#ifdef ERRNO_VAR19#include "Inputs/errno_var.h"20#endif21#ifdef ERRNO_FUNC22#include "Inputs/errno_func.h"23#endif24 25void clang_analyzer_eval(int);26void ErrnoTesterChecker_setErrno(int);27int ErrnoTesterChecker_getErrno();28int ErrnoTesterChecker_setErrnoIfError();29int ErrnoTesterChecker_setErrnoIfErrorRange();30int ErrnoTesterChecker_setErrnoCheckState();31 32void something();33 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 50void testRange(int X) {51 if (X > 0) {52 ErrnoTesterChecker_setErrno(X);53 clang_analyzer_eval(errno > 0); // expected-warning{{TRUE}}54 }55}56 57void testIfError() {58 if (ErrnoTesterChecker_setErrnoIfError())59 clang_analyzer_eval(errno == 11); // expected-warning{{TRUE}}60}61 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 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 94void testErrnoCheck1() {95 // If the function returns error result code that is out-of-band (not a valid96 // non-error return value) the value of 'errno' can be checked but it is not97 // required to do so.98 int X = ErrnoTesterChecker_setErrnoCheckState();99 if (X == 1) {100 if (errno) { // no warning101 }102 }103 X = ErrnoTesterChecker_setErrnoCheckState();104 if (X == 1) {105 errno = 0; // no warning106 }107}108 109void testErrnoCheck2() {110 // If the function returns an in-band error result the value of 'errno' is111 // required to be checked to verify if error happened.112 // The same applies to other functions that can indicate failure only by113 // 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 127void testErrnoCheck3() {128 int X = ErrnoTesterChecker_setErrnoCheckState();129 if (X == 2) {130 if (errno) {131 }132 errno = 0; // no warning after 'errno' was read133 }134 X = ErrnoTesterChecker_setErrnoCheckState();135 if (X == 2) {136 int A = errno;137 errno = 0; // no warning after 'errno' was read138 }139}140 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 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 157void testErrnoCheckStateInvalidate() {158 int X = ErrnoTesterChecker_setErrnoCheckState();159 if (X == 0) {160 something();161 if (errno) { // no warning after an invalidating function call162 }163 }164 X = ErrnoTesterChecker_setErrnoCheckState();165 if (X == 0) {166 printf("%i", 1);167 if (errno) { // no warning after an invalidating standard function call168 }169 }170}171 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 invalidation179 }180}181 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 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 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 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 210void test_switch_cond() {211 ErrnoTesterChecker_setErrnoIfError();212 switch (errno) {}213 // expected-warning@-1{{An undefined value may be read from 'errno'}}214}215 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 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 228void test_errno_store_into_variable() {229 ErrnoTesterChecker_setErrnoIfError();230 int a = errno; // AllowNonConditionErrnoRead is on by default, no warning231}232 233void test_errno_store_into_variable_in_expr() {234 ErrnoTesterChecker_setErrnoIfError();235 int a = errno > 1; // AllowNonConditionErrnoRead is on by default, no warning236}237 238int test_errno_return() {239 ErrnoTesterChecker_setErrnoIfError();240 return errno;241}242 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 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 257int f(int);258 259void test_errno_in_condition_in_function_call() {260 ErrnoTesterChecker_setErrnoIfError();261 if (f(errno) != 0) {262 }263}264