1 // RUN: %clang_analyze_cc1 -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s 2 // RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s 3 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s 4 // RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s 5 // RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s 6 7 void clang_analyzer_eval(int); 8 9 int glob; 10 11 typedef struct FILE FILE; 12 #define EOF -1 13 14 int getc(FILE *); 15 void test_getc(FILE *fp) { 16 int x; 17 while ((x = getc(fp)) != EOF) { 18 clang_analyzer_eval(x > 255); // expected-warning{{FALSE}} 19 clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}} 20 } 21 } 22 23 int fgetc(FILE *); 24 void test_fgets(FILE *fp) { 25 clang_analyzer_eval(fgetc(fp) < 256); // expected-warning{{TRUE}} 26 clang_analyzer_eval(fgetc(fp) >= 0); // expected-warning{{UNKNOWN}} 27 } 28 29 30 typedef typeof(sizeof(int)) size_t; 31 typedef signed long ssize_t; 32 ssize_t read(int, void *, size_t); 33 ssize_t write(int, const void *, size_t); 34 void test_read_write(int fd, char *buf) { 35 glob = 1; 36 ssize_t x = write(fd, buf, 10); 37 clang_analyzer_eval(glob); // expected-warning{{UNKNOWN}} 38 if (x >= 0) { 39 clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}} 40 ssize_t y = read(fd, &glob, sizeof(glob)); 41 if (y >= 0) { 42 clang_analyzer_eval(y <= sizeof(glob)); // expected-warning{{TRUE}} 43 } else { 44 // -1 overflows on promotion! 45 clang_analyzer_eval(y <= sizeof(glob)); // expected-warning{{FALSE}} 46 } 47 } else { 48 clang_analyzer_eval(x == -1); // expected-warning{{TRUE}} 49 } 50 } 51 52 size_t fread(void *, size_t, size_t, FILE *); 53 size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); 54 void test_fread_fwrite(FILE *fp, int *buf) { 55 size_t x = fwrite(buf, sizeof(int), 10, fp); 56 clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}} 57 size_t y = fread(buf, sizeof(int), 10, fp); 58 clang_analyzer_eval(y <= 10); // expected-warning{{TRUE}} 59 size_t z = fwrite(buf, sizeof(int), y, fp); 60 // FIXME: should be TRUE once symbol-symbol constraint support is improved. 61 clang_analyzer_eval(z <= y); // expected-warning{{UNKNOWN}} 62 } 63 64 ssize_t getline(char **, size_t *, FILE *); 65 void test_getline(FILE *fp) { 66 char *line = 0; 67 size_t n = 0; 68 ssize_t len; 69 while ((len = getline(&line, &n, fp)) != -1) { 70 clang_analyzer_eval(len == 0); // expected-warning{{FALSE}} 71 } 72 } 73 74 int isascii(int); 75 void test_isascii(int x) { 76 clang_analyzer_eval(isascii(123)); // expected-warning{{TRUE}} 77 clang_analyzer_eval(isascii(-1)); // expected-warning{{FALSE}} 78 if (isascii(x)) { 79 clang_analyzer_eval(x < 128); // expected-warning{{TRUE}} 80 clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}} 81 } else { 82 if (x > 42) 83 clang_analyzer_eval(x >= 128); // expected-warning{{TRUE}} 84 else 85 clang_analyzer_eval(x < 0); // expected-warning{{TRUE}} 86 } 87 glob = 1; 88 isascii('a'); 89 clang_analyzer_eval(glob); // expected-warning{{TRUE}} 90 } 91 92 int islower(int); 93 void test_islower(int x) { 94 clang_analyzer_eval(islower('x')); // expected-warning{{TRUE}} 95 clang_analyzer_eval(islower('X')); // expected-warning{{FALSE}} 96 if (islower(x)) 97 clang_analyzer_eval(x < 'a'); // expected-warning{{FALSE}} 98 } 99 100 int getchar(void); 101 void test_getchar() { 102 int x = getchar(); 103 if (x == EOF) 104 return; 105 clang_analyzer_eval(x < 0); // expected-warning{{FALSE}} 106 clang_analyzer_eval(x < 256); // expected-warning{{TRUE}} 107 } 108 109 int isalpha(int); 110 void test_isalpha() { 111 clang_analyzer_eval(isalpha(']')); // expected-warning{{FALSE}} 112 clang_analyzer_eval(isalpha('Q')); // expected-warning{{TRUE}} 113 clang_analyzer_eval(isalpha(128)); // expected-warning{{UNKNOWN}} 114 } 115 116 int isalnum(int); 117 void test_alnum() { 118 clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}} 119 clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}} 120 } 121 122 int isblank(int); 123 void test_isblank() { 124 clang_analyzer_eval(isblank('\t')); // expected-warning{{TRUE}} 125 clang_analyzer_eval(isblank(' ')); // expected-warning{{TRUE}} 126 clang_analyzer_eval(isblank('\n')); // expected-warning{{FALSE}} 127 } 128 129 int ispunct(int); 130 void test_ispunct(int x) { 131 clang_analyzer_eval(ispunct(' ')); // expected-warning{{FALSE}} 132 clang_analyzer_eval(ispunct(-1)); // expected-warning{{FALSE}} 133 clang_analyzer_eval(ispunct('#')); // expected-warning{{TRUE}} 134 clang_analyzer_eval(ispunct('_')); // expected-warning{{TRUE}} 135 if (ispunct(x)) 136 clang_analyzer_eval(x < 127); // expected-warning{{TRUE}} 137 } 138 139 int isupper(int); 140 void test_isupper(int x) { 141 if (isupper(x)) 142 clang_analyzer_eval(x < 'A'); // expected-warning{{FALSE}} 143 } 144 145 int isgraph(int); 146 int isprint(int); 147 void test_isgraph_isprint(int x) { 148 char y = x; 149 if (isgraph(y)) 150 clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}} 151 } 152 153 int isdigit(int); 154 void test_mixed_branches(int x) { 155 if (isdigit(x)) { 156 clang_analyzer_eval(isgraph(x)); // expected-warning{{TRUE}} 157 clang_analyzer_eval(isblank(x)); // expected-warning{{FALSE}} 158 } else if (isascii(x)) { 159 // isalnum() bifurcates here. 160 clang_analyzer_eval(isalnum(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 161 clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}} 162 } 163 } 164 165 int isspace(int); 166 void test_isspace(int x) { 167 if (!isascii(x)) 168 return; 169 char y = x; 170 if (y == ' ') 171 clang_analyzer_eval(isspace(x)); // expected-warning{{TRUE}} 172 } 173 174 int isxdigit(int); 175 void test_isxdigit(int x) { 176 if (isxdigit(x) && isupper(x)) { 177 clang_analyzer_eval(x >= 'A'); // expected-warning{{TRUE}} 178 clang_analyzer_eval(x <= 'F'); // expected-warning{{TRUE}} 179 } 180 } 181 182 void test_call_by_pointer() { 183 typedef int (*func)(int); 184 func f = isascii; 185 clang_analyzer_eval(f('A')); // expected-warning{{TRUE}} 186 f = ispunct; 187 clang_analyzer_eval(f('A')); // expected-warning{{FALSE}} 188 } 189