Clang Project

clang_source_code/test/Analysis/std-c-library-functions.c
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
7void clang_analyzer_eval(int);
8
9int glob;
10
11typedef struct FILE FILE;
12#define EOF -1
13
14int getc(FILE *);
15void 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
23int fgetc(FILE *);
24void 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
30typedef typeof(sizeof(int)) size_t;
31typedef signed long ssize_t;
32ssize_t read(int, void *, size_t);
33ssize_t write(int, const void *, size_t);
34void 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
52size_t fread(void *, size_t, size_t, FILE *);
53size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict);
54void 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
63ssize_t getline(char **, size_t *, FILE *);
64void 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
73int isascii(int);
74void 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
91int islower(int);
92void 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
99int getchar(void);
100void 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
108int isalpha(int);
109void 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
115int isalnum(int);
116void test_alnum() {
117  clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}}
118  clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}}
119}
120
121int isblank(int);
122void 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
128int ispunct(int);
129void 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
138int isupper(int);
139void test_isupper(int x) {
140  if (isupper(x))
141    clang_analyzer_eval(x < 'A'); // expected-warning{{FALSE}}
142}
143
144int isgraph(int);
145int isprint(int);
146void test_isgraph_isprint(int x) {
147  char y = x;
148  if (isgraph(y))
149    clang_analyzer_eval(isprint(x)); // expected-warning{{TRUE}}
150}
151
152int isdigit(int);
153void 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
164int isspace(int);
165void 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
173int isxdigit(int);
174void 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
181void 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