1 | // RUN: %clang_analyze_cc1 -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s |
2 | // RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s |
3 | // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s |
4 | // RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s |
5 | // RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=apiModeling.StdCLibraryFunctions,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %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 | clang_analyzer_eval(z <= y); // expected-warning{{TRUE}} |
61 | } |
62 | |
63 | ssize_t getline(char **, size_t *, FILE *); |
64 | void test_getline(FILE *fp) { |
65 | char *line = 0; |
66 | size_t n = 0; |
67 | ssize_t len; |
68 | while ((len = getline(&line, &n, fp)) != -1) { |
69 | clang_analyzer_eval(len == 0); // expected-warning{{FALSE}} |
70 | } |
71 | } |
72 | |
73 | int isascii(int); |
74 | void test_isascii(int x) { |
75 | clang_analyzer_eval(isascii(123)); // expected-warning{{TRUE}} |
76 | clang_analyzer_eval(isascii(-1)); // expected-warning{{FALSE}} |
77 | if (isascii(x)) { |
78 | clang_analyzer_eval(x < 128); // expected-warning{{TRUE}} |
79 | clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}} |
80 | } else { |
81 | if (x > 42) |
82 | clang_analyzer_eval(x >= 128); // expected-warning{{TRUE}} |
83 | else |
84 | clang_analyzer_eval(x < 0); // expected-warning{{TRUE}} |
85 | } |
86 | glob = 1; |
87 | isascii('a'); |
88 | clang_analyzer_eval(glob); // expected-warning{{TRUE}} |
89 | } |
90 | |
91 | int islower(int); |
92 | void test_islower(int x) { |
93 | clang_analyzer_eval(islower('x')); // expected-warning{{TRUE}} |
94 | clang_analyzer_eval(islower('X')); // expected-warning{{FALSE}} |
95 | if (islower(x)) |
96 | clang_analyzer_eval(x < 'a'); // expected-warning{{FALSE}} |
97 | } |
98 | |
99 | int getchar(void); |
100 | void test_getchar() { |
101 | int x = getchar(); |
102 | if (x == EOF) |
103 | return; |
104 | clang_analyzer_eval(x < 0); // expected-warning{{FALSE}} |
105 | clang_analyzer_eval(x < 256); // expected-warning{{TRUE}} |
106 | } |
107 | |
108 | int isalpha(int); |
109 | void test_isalpha() { |
110 | clang_analyzer_eval(isalpha(']')); // expected-warning{{FALSE}} |
111 | clang_analyzer_eval(isalpha('Q')); // expected-warning{{TRUE}} |
112 | clang_analyzer_eval(isalpha(128)); // expected-warning{{UNKNOWN}} |
113 | } |
114 | |
115 | int isalnum(int); |
116 | void test_alnum() { |
117 | clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}} |
118 | clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}} |
119 | } |
120 | |
121 | int isblank(int); |
122 | void test_isblank() { |
123 | clang_analyzer_eval(isblank('\t')); // expected-warning{{TRUE}} |
124 | clang_analyzer_eval(isblank(' ')); // expected-warning{{TRUE}} |
125 | clang_analyzer_eval(isblank('\n')); // expected-warning{{FALSE}} |
126 | } |
127 | |
128 | int ispunct(int); |
129 | void test_ispunct(int x) { |
130 | clang_analyzer_eval(ispunct(' ')); // expected-warning{{FALSE}} |
131 | clang_analyzer_eval(ispunct(-1)); // expected-warning{{FALSE}} |
132 | clang_analyzer_eval(ispunct('#')); // expected-warning{{TRUE}} |
133 | clang_analyzer_eval(ispunct('_')); // expected-warning{{TRUE}} |
134 | if (ispunct(x)) |
135 | clang_analyzer_eval(x < 127); // expected-warning{{TRUE}} |
136 | } |
137 | |
138 | int isupper(int); |
139 | void test_isupper(int x) { |
140 | if (isupper(x)) |
141 | clang_analyzer_eval(x < 'A'); // expected-warning{{FALSE}} |
142 | } |
143 | |
144 | int isgraph(int); |
145 | int isprint(int); |
146 | void test_isgraph_isprint(int x) { |
147 | char y = x; |
148 | if (isgraph(y)) |
149 | clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}} |
150 | } |
151 | |
152 | int isdigit(int); |
153 | void test_mixed_branches(int x) { |
154 | if (isdigit(x)) { |
155 | clang_analyzer_eval(isgraph(x)); // expected-warning{{TRUE}} |
156 | clang_analyzer_eval(isblank(x)); // expected-warning{{FALSE}} |
157 | } else if (isascii(x)) { |
158 | // isalnum() bifurcates here. |
159 | clang_analyzer_eval(isalnum(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}} |
160 | clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}} // expected-warning{{FALSE}} |
161 | } |
162 | } |
163 | |
164 | int isspace(int); |
165 | void test_isspace(int x) { |
166 | if (!isascii(x)) |
167 | return; |
168 | char y = x; |
169 | if (y == ' ') |
170 | clang_analyzer_eval(isspace(x)); // expected-warning{{TRUE}} |
171 | } |
172 | |
173 | int isxdigit(int); |
174 | void test_isxdigit(int x) { |
175 | if (isxdigit(x) && isupper(x)) { |
176 | clang_analyzer_eval(x >= 'A'); // expected-warning{{TRUE}} |
177 | clang_analyzer_eval(x <= 'F'); // expected-warning{{TRUE}} |
178 | } |
179 | } |
180 | |
181 | void test_call_by_pointer() { |
182 | typedef int (*func)(int); |
183 | func f = isascii; |
184 | clang_analyzer_eval(f('A')); // expected-warning{{TRUE}} |
185 | f = ispunct; |
186 | clang_analyzer_eval(f('A')); // expected-warning{{FALSE}} |
187 | } |
188 | |