178 lines · c
1// RUN: %clang_analyze_cc1 -verify %s \2// RUN: -analyzer-checker=core \3// RUN: -analyzer-checker=debug.ExprInspection \4// RUN: -analyzer-checker=unix.StdCLibraryFunctions \5// RUN: -analyzer-checker=apiModeling.Errno \6// RUN: -analyzer-checker=unix.Errno \7// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true8 9#include "Inputs/errno_var.h"10#include "Inputs/std-c-library-functions-POSIX.h"11 12#define NULL ((void *) 0)13 14void clang_analyzer_warnIfReached();15void clang_analyzer_eval(int);16 17int unsafe_errno_read(int sock, void *data, int data_size) {18 if (send(sock, data, data_size, 0) != data_size) {19 if (errno == 1) {20 // expected-warning@-1{{An undefined value may be read from 'errno'}}21 return 0;22 }23 }24 return 1;25}26 27int errno_lseek(int fildes, off_t offset) {28 off_t result = lseek(fildes, offset, 0);29 if (result == (off_t)-1) {30 // Failure path.31 // check if the function is modeled32 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}33 return 2;34 }35 if (result != offset) {36 // Not success path (?)37 // not sure if this is a valid case, allow to check 'errno'38 if (errno == 1) { // no warning39 return 1;40 }41 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}42 }43 if (result == offset) {44 // The checker does not differentiate for this case.45 // In general case no relation exists between the arg 2 and the returned46 // value, only for SEEK_SET.47 if (errno == 1) { // no warning48 return 1;49 }50 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}51 }52 return 0;53}54 55void errno_mkstemp(char *template) {56 int FD = mkstemp(template);57 if (FD >= 0) {58 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}59 close(FD);60 } else {61 clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}62 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}63 if (errno) {} // no warning64 }65}66 67void errno_mkdtemp(char *template) {68 char *Dir = mkdtemp(template);69 if (Dir == NULL) {70 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}71 if (errno) {} // no warning72 } else {73 clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}74 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}75 }76}77 78typedef char* CHAR_PTR;79void errno_mkdtemp2(CHAR_PTR template) {80 CHAR_PTR Dir = mkdtemp(template);81 if (Dir == NULL) {82 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}83 if (errno) {} // no warning84 } else {85 clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}86 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}87 }88}89 90typedef char const* CONST_CHAR_PTR;91void errno_mkdtemp3(CHAR_PTR template) {92 CONST_CHAR_PTR Dir = mkdtemp(template);93 if (Dir == NULL) {94 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}95 if (errno) {} // no warning96 } else {97 clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}98 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}99 }100}101 102void errno_getcwd_buf_nonnull(char *Buf, size_t Sz) {103 if (Buf == NULL)104 return;105 char *Path = getcwd(Buf, Sz);106 if (Sz == 0) {107 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}108 clang_analyzer_eval(Path == NULL); // expected-warning{{TRUE}}109 if (errno) {} // no warning110 } else if (Path == NULL) {111 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}112 if (errno) {} // no warning113 } else {114 clang_analyzer_eval(Path == Buf); // expected-warning{{TRUE}}115 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}116 }117}118 119void errno_getcwd_buf_null() {120 // POSIX does not mention this case but many implementations (Linux, FreeBSD) work this way.121 char *Path = getcwd(NULL, 1);122 if (Path == NULL) {123 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}124 if (errno) {} // no warning125 } else {126 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}127 }128}129 130void errno_execv(char *Path, char * Argv[]) {131 int Ret = execv(Path, Argv);132 clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}133 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}134 if (errno) {} // no warning135}136 137void errno_execvp(char *File, char * Argv[]) {138 int Ret = execvp(File, Argv);139 clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}140 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}141 if (errno) {} // no warning142}143 144void errno_popen(void) {145 FILE *F = popen("xxx", "r");146 if (!F) {147 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}148 if (errno) {} // no-warning149 } else {150 if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}151 pclose(F);152 }153}154 155void errno_pclose(void) {156 FILE *F = popen("xx", "w");157 if (!F)158 return;159 int Ret = pclose(F);160 if (Ret == -1) {161 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}162 if (errno) {} // no-warning163 } else {164 clang_analyzer_eval(Ret >= 0); // expected-warning{{TRUE}}165 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}166 }167}168 169void errno_realpath(char *Path, char *Buf) {170 char *Ret = realpath(Path, Buf);171 if (!Ret) {172 clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}173 if (errno) {} // no-warning174 } else {175 if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}176 }177}178