blob: c59e4429f4194d39070e8b7ed51e4dabb8648537 [file] [log] [blame]
Gabor Marton94061df2020-03-20 16:20:53 +01001// Check the basic reporting/warning and the application of constraints.
2// RUN: %clang_analyze_cc1 %s \
3// RUN: -analyzer-checker=core \
4// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
Artem Dergacheve42e5e42020-05-19 22:43:10 +03005// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \
Gabor Marton15252322020-04-02 16:59:02 +02006// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
Gabor Marton94061df2020-03-20 16:20:53 +01007// RUN: -analyzer-checker=debug.ExprInspection \
8// RUN: -triple x86_64-unknown-linux-gnu \
9// RUN: -verify=report
10
11// Check the bugpath related to the reports.
12// RUN: %clang_analyze_cc1 %s \
13// RUN: -analyzer-checker=core \
14// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
Artem Dergacheve42e5e42020-05-19 22:43:10 +030015// RUN: -analyzer-checker=alpha.apiModeling.StdCLibraryFunctionArgs \
Gabor Marton15252322020-04-02 16:59:02 +020016// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \
Gabor Marton94061df2020-03-20 16:20:53 +010017// RUN: -analyzer-checker=debug.ExprInspection \
18// RUN: -triple x86_64-unknown-linux-gnu \
19// RUN: -analyzer-output=text \
20// RUN: -verify=bugpath
21
22void clang_analyzer_eval(int);
23
24int glob;
25
26#define EOF -1
27
28int isalnum(int);
29
30void test_alnum_concrete(int v) {
31 int ret = isalnum(256); // \
32 // report-warning{{Function argument constraint is not satisfied}} \
33 // bugpath-warning{{Function argument constraint is not satisfied}} \
34 // bugpath-note{{Function argument constraint is not satisfied}}
35 (void)ret;
36}
37
38void test_alnum_symbolic(int x) {
39 int ret = isalnum(x);
40 (void)ret;
41
42 clang_analyzer_eval(EOF <= x && x <= 255); // \
43 // report-warning{{TRUE}} \
44 // bugpath-warning{{TRUE}} \
45 // bugpath-note{{TRUE}} \
46 // bugpath-note{{Left side of '&&' is true}} \
47 // bugpath-note{{'x' is <= 255}}
48
49}
50
51void test_alnum_symbolic2(int x) {
52 if (x > 255) { // \
53 // bugpath-note{{Assuming 'x' is > 255}} \
54 // bugpath-note{{Taking true branch}}
55
56 int ret = isalnum(x); // \
57 // report-warning{{Function argument constraint is not satisfied}} \
58 // bugpath-warning{{Function argument constraint is not satisfied}} \
59 // bugpath-note{{Function argument constraint is not satisfied}}
60
61 (void)ret;
62 }
63}
Gabor Martonededa652020-03-20 17:23:23 +010064
65typedef struct FILE FILE;
66typedef typeof(sizeof(int)) size_t;
Gabor Marton8f961392020-04-03 17:01:00 +020067size_t fread(void *restrict, size_t, size_t, FILE *);
Gabor Martonededa652020-03-20 17:23:23 +010068void test_notnull_concrete(FILE *fp) {
69 fread(0, sizeof(int), 10, fp); // \
70 // report-warning{{Function argument constraint is not satisfied}} \
71 // bugpath-warning{{Function argument constraint is not satisfied}} \
72 // bugpath-note{{Function argument constraint is not satisfied}}
73}
74void test_notnull_symbolic(FILE *fp, int *buf) {
75 fread(buf, sizeof(int), 10, fp);
76 clang_analyzer_eval(buf != 0); // \
77 // report-warning{{TRUE}} \
78 // bugpath-warning{{TRUE}} \
79 // bugpath-note{{TRUE}} \
80 // bugpath-note{{'buf' is not equal to null}}
81}
82void test_notnull_symbolic2(FILE *fp, int *buf) {
83 if (!buf) // bugpath-note{{Assuming 'buf' is null}} \
84 // bugpath-note{{Taking true branch}}
85 fread(buf, sizeof(int), 10, fp); // \
86 // report-warning{{Function argument constraint is not satisfied}} \
87 // bugpath-warning{{Function argument constraint is not satisfied}} \
88 // bugpath-note{{Function argument constraint is not satisfied}}
89}
Gabor Marton15252322020-04-02 16:59:02 +020090
91int __two_constrained_args(int, int);
92void test_constraints_on_multiple_args(int x, int y) {
93 // State split should not happen here. I.e. x == 1 should not be evaluated
94 // FALSE.
95 __two_constrained_args(x, y);
96 clang_analyzer_eval(x == 1); // \
97 // report-warning{{TRUE}} \
98 // bugpath-warning{{TRUE}} \
99 // bugpath-note{{TRUE}}
100 clang_analyzer_eval(y == 1); // \
101 // report-warning{{TRUE}} \
102 // bugpath-warning{{TRUE}} \
103 // bugpath-note{{TRUE}}
104}
105
106int __arg_constrained_twice(int);
107void test_multiple_constraints_on_same_arg(int x) {
108 __arg_constrained_twice(x);
109 // Check that both constraints are applied and only one branch is there.
110 clang_analyzer_eval(x < 1 || x > 2); // \
111 // report-warning{{TRUE}} \
112 // bugpath-warning{{TRUE}} \
113 // bugpath-note{{TRUE}} \
114 // bugpath-note{{Assuming 'x' is < 1}} \
115 // bugpath-note{{Left side of '||' is true}}
116}
Gabor Marton8f961392020-04-03 17:01:00 +0200117
118int __variadic(void *stream, const char *format, ...);
119void test_arg_constraint_on_variadic_fun() {
120 __variadic(0, "%d%d", 1, 2); // \
121 // report-warning{{Function argument constraint is not satisfied}} \
122 // bugpath-warning{{Function argument constraint is not satisfied}} \
123 // bugpath-note{{Function argument constraint is not satisfied}}
124}
Gabor Martonbd03ef12020-03-30 17:47:48 +0200125
126int __buf_size_arg_constraint(const void *, size_t);
127void test_buf_size_concrete() {
128 char buf[3]; // bugpath-note{{'buf' initialized here}}
129 __buf_size_arg_constraint(buf, 4); // \
130 // report-warning{{Function argument constraint is not satisfied}} \
131 // bugpath-warning{{Function argument constraint is not satisfied}} \
132 // bugpath-note{{Function argument constraint is not satisfied}}
133}
134void test_buf_size_symbolic(int s) {
135 char buf[3];
136 __buf_size_arg_constraint(buf, s);
137 clang_analyzer_eval(s <= 3); // \
138 // report-warning{{TRUE}} \
139 // bugpath-warning{{TRUE}} \
140 // bugpath-note{{TRUE}} \
141 // bugpath-note{{'s' is <= 3}}
142}
143void test_buf_size_symbolic_and_offset(int s) {
144 char buf[3];
145 __buf_size_arg_constraint(buf + 1, s);
146 clang_analyzer_eval(s <= 2); // \
147 // report-warning{{TRUE}} \
148 // bugpath-warning{{TRUE}} \
149 // bugpath-note{{TRUE}} \
150 // bugpath-note{{'s' is <= 2}}
151}