1957014daSBalázs Kéri // RUN: %clang_analyze_cc1 -verify %s \
2957014daSBalázs Kéri // RUN: -analyzer-checker=core \
3957014daSBalázs Kéri // RUN: -analyzer-checker=debug.ExprInspection \
4c202a17dSBalázs Kéri // RUN: -analyzer-checker=unix.StdCLibraryFunctions \
5957014daSBalázs Kéri // RUN: -analyzer-checker=apiModeling.Errno \
672d3bf2bSBalázs Kéri // RUN: -analyzer-checker=unix.Errno \
7c202a17dSBalázs Kéri // RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
8957014daSBalázs Kéri
9957014daSBalázs Kéri #include "Inputs/errno_var.h"
103db749afSBen Shi #include "Inputs/std-c-library-functions-POSIX.h"
11957014daSBalázs Kéri
123db749afSBen Shi #define NULL ((void *) 0)
13957014daSBalázs Kéri
14957014daSBalázs Kéri void clang_analyzer_warnIfReached();
15957014daSBalázs Kéri void clang_analyzer_eval(int);
16957014daSBalázs Kéri
unsafe_errno_read(int sock,void * data,int data_size)17957014daSBalázs Kéri int unsafe_errno_read(int sock, void *data, int data_size) {
18957014daSBalázs Kéri if (send(sock, data, data_size, 0) != data_size) {
19957014daSBalázs Kéri if (errno == 1) {
20957014daSBalázs Kéri // expected-warning@-1{{An undefined value may be read from 'errno'}}
21957014daSBalázs Kéri return 0;
22957014daSBalázs Kéri }
23957014daSBalázs Kéri }
24957014daSBalázs Kéri return 1;
25957014daSBalázs Kéri }
26957014daSBalázs Kéri
errno_lseek(int fildes,off_t offset)27957014daSBalázs Kéri int errno_lseek(int fildes, off_t offset) {
28957014daSBalázs Kéri off_t result = lseek(fildes, offset, 0);
29957014daSBalázs Kéri if (result == (off_t)-1) {
30957014daSBalázs Kéri // Failure path.
31957014daSBalázs Kéri // check if the function is modeled
32957014daSBalázs Kéri clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
33957014daSBalázs Kéri return 2;
34957014daSBalázs Kéri }
35957014daSBalázs Kéri if (result != offset) {
36957014daSBalázs Kéri // Not success path (?)
37957014daSBalázs Kéri // not sure if this is a valid case, allow to check 'errno'
38957014daSBalázs Kéri if (errno == 1) { // no warning
39957014daSBalázs Kéri return 1;
40957014daSBalázs Kéri }
41957014daSBalázs Kéri clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
42957014daSBalázs Kéri }
43957014daSBalázs Kéri if (result == offset) {
44957014daSBalázs Kéri // The checker does not differentiate for this case.
45957014daSBalázs Kéri // In general case no relation exists between the arg 2 and the returned
46957014daSBalázs Kéri // value, only for SEEK_SET.
47957014daSBalázs Kéri if (errno == 1) { // no warning
48957014daSBalázs Kéri return 1;
49957014daSBalázs Kéri }
50957014daSBalázs Kéri clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
51957014daSBalázs Kéri }
52957014daSBalázs Kéri return 0;
53957014daSBalázs Kéri }
543db749afSBen Shi
errno_mkstemp(char * template)553db749afSBen Shi void errno_mkstemp(char *template) {
563db749afSBen Shi int FD = mkstemp(template);
573db749afSBen Shi if (FD >= 0) {
583db749afSBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
593db749afSBen Shi close(FD);
603db749afSBen Shi } else {
613db749afSBen Shi clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}
623db749afSBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
633db749afSBen Shi if (errno) {} // no warning
643db749afSBen Shi }
653db749afSBen Shi }
663db749afSBen Shi
errno_mkdtemp(char * template)673db749afSBen Shi void errno_mkdtemp(char *template) {
683db749afSBen Shi char *Dir = mkdtemp(template);
693db749afSBen Shi if (Dir == NULL) {
703db749afSBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
713db749afSBen Shi if (errno) {} // no warning
723db749afSBen Shi } else {
733db749afSBen Shi clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
743db749afSBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
753db749afSBen Shi }
763db749afSBen Shi }
777dd20637SBen Shi
78*0851d7b0SCongcong Cai typedef char* CHAR_PTR;
errno_mkdtemp2(CHAR_PTR template)79*0851d7b0SCongcong Cai void errno_mkdtemp2(CHAR_PTR template) {
80*0851d7b0SCongcong Cai CHAR_PTR Dir = mkdtemp(template);
81*0851d7b0SCongcong Cai if (Dir == NULL) {
82*0851d7b0SCongcong Cai clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
83*0851d7b0SCongcong Cai if (errno) {} // no warning
84*0851d7b0SCongcong Cai } else {
85*0851d7b0SCongcong Cai clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
86*0851d7b0SCongcong Cai if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
87*0851d7b0SCongcong Cai }
88*0851d7b0SCongcong Cai }
89*0851d7b0SCongcong Cai
90*0851d7b0SCongcong Cai typedef char const* CONST_CHAR_PTR;
errno_mkdtemp3(CHAR_PTR template)91*0851d7b0SCongcong Cai void errno_mkdtemp3(CHAR_PTR template) {
92*0851d7b0SCongcong Cai CONST_CHAR_PTR Dir = mkdtemp(template);
93*0851d7b0SCongcong Cai if (Dir == NULL) {
94*0851d7b0SCongcong Cai clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
95*0851d7b0SCongcong Cai if (errno) {} // no warning
96*0851d7b0SCongcong Cai } else {
97*0851d7b0SCongcong Cai clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
98*0851d7b0SCongcong Cai if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
99*0851d7b0SCongcong Cai }
100*0851d7b0SCongcong Cai }
101*0851d7b0SCongcong Cai
errno_getcwd(char * Buf,size_t Sz)1027dd20637SBen Shi void errno_getcwd(char *Buf, size_t Sz) {
1037dd20637SBen Shi char *Path = getcwd(Buf, Sz);
1047dd20637SBen Shi if (Sz == 0) {
1057dd20637SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
1067dd20637SBen Shi clang_analyzer_eval(Path == NULL); // expected-warning{{TRUE}}
1077dd20637SBen Shi if (errno) {} // no warning
1087dd20637SBen Shi } else if (Path == NULL) {
1097dd20637SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
1107dd20637SBen Shi if (errno) {} // no warning
1117dd20637SBen Shi } else {
1127dd20637SBen Shi clang_analyzer_eval(Path == Buf); // expected-warning{{TRUE}}
1137dd20637SBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
1147dd20637SBen Shi }
1157dd20637SBen Shi }
116b7f986d9SBen Shi
errno_execv(char * Path,char * Argv[])117b7f986d9SBen Shi void errno_execv(char *Path, char * Argv[]) {
118b7f986d9SBen Shi int Ret = execv(Path, Argv);
119b7f986d9SBen Shi clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}
120b7f986d9SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
121b7f986d9SBen Shi if (errno) {} // no warning
122b7f986d9SBen Shi }
123b7f986d9SBen Shi
errno_execvp(char * File,char * Argv[])124b7f986d9SBen Shi void errno_execvp(char *File, char * Argv[]) {
125b7f986d9SBen Shi int Ret = execvp(File, Argv);
126b7f986d9SBen Shi clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}
127b7f986d9SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
128b7f986d9SBen Shi if (errno) {} // no warning
129b7f986d9SBen Shi }
130ff05c308SBen Shi
errno_popen(void)131ff05c308SBen Shi void errno_popen(void) {
132ff05c308SBen Shi FILE *F = popen("xxx", "r");
133ff05c308SBen Shi if (!F) {
134ff05c308SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
135ff05c308SBen Shi if (errno) {} // no-warning
136ff05c308SBen Shi } else {
137ff05c308SBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
138ff05c308SBen Shi pclose(F);
139ff05c308SBen Shi }
140ff05c308SBen Shi }
141ff05c308SBen Shi
errno_pclose(void)142ff05c308SBen Shi void errno_pclose(void) {
143ff05c308SBen Shi FILE *F = popen("xx", "w");
144ff05c308SBen Shi if (!F)
145ff05c308SBen Shi return;
146ff05c308SBen Shi int Ret = pclose(F);
147ff05c308SBen Shi if (Ret == -1) {
148ff05c308SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
149ff05c308SBen Shi if (errno) {} // no-warning
150ff05c308SBen Shi } else {
151ff05c308SBen Shi clang_analyzer_eval(Ret >= 0); // expected-warning{{TRUE}}
152ff05c308SBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
153ff05c308SBen Shi }
154ff05c308SBen Shi }
155c12f30c7SBen Shi
errno_realpath(char * Path,char * Buf)156c12f30c7SBen Shi void errno_realpath(char *Path, char *Buf) {
157c12f30c7SBen Shi char *Ret = realpath(Path, Buf);
158c12f30c7SBen Shi if (!Ret) {
159c12f30c7SBen Shi clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
160c12f30c7SBen Shi if (errno) {} // no-warning
161c12f30c7SBen Shi } else {
162c12f30c7SBen Shi if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
163c12f30c7SBen Shi }
164c12f30c7SBen Shi }
165