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