Skip to content

Commit ddc5d40

Browse files
committed
[clang][analyzer] Make messages of StdCLibraryFunctionsChecker user-friendly
Warnings and notes of checker alpha.unix.StdLibraryFunctionArgs are improved. Previously one warning and one note was emitted for every finding, now one warning is emitted only that contains a detailed description of the found issue. Reviewed By: Szelethus Differential Revision: https://reviews.llvm.org/D143194
1 parent c1eb3db commit ddc5d40

8 files changed

+533
-259
lines changed

clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp

Lines changed: 326 additions & 92 deletions
Large diffs are not rendered by default.

clang/test/Analysis/std-c-library-functions-arg-constraints-note-tags.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ int clang_analyzer_getExtent(void *);
1919
// Check NotNullConstraint assumption notes.
2020
int __not_null(int *);
2121
int test_not_null_note(int *x, int y) {
22-
__not_null(x); // expected-note{{Assuming the 1st argument is not NULL}}
22+
__not_null(x); // expected-note{{Assuming the 1st argument to '__not_null' is not NULL}}
2323
if (x) // expected-note{{'x' is non-null}} \
2424
// expected-note{{Taking true branch}}
2525
if (!y) // expected-note{{Assuming 'y' is 0}} \
@@ -33,15 +33,15 @@ int test_not_null_note(int *x, int y) {
3333
// Check the RangeConstraint assumption notes.
3434
int __single_val_0(int); // [0, 0]
3535
int test_range_constraint_note(int x, int y) {
36-
__single_val_0(x); // expected-note{{Assuming the 1st argument is within the range [0, 0]}}
36+
__single_val_0(x); // expected-note{{Assuming the 1st argument to '__single_val_0' is zero}}
3737
return y / x; // expected-warning{{Division by zero}} \
3838
// expected-note{{Division by zero}}
3939
}
4040

4141
// Check the BufferSizeConstraint assumption notes.
4242
int __buf_size_arg_constraint_concrete(const void *buf); // size of buf must be >= 10
4343
void test_buffer_size_note(char *buf, int y) {
44-
__buf_size_arg_constraint_concrete(buf); // expected-note {{Assuming the size of the 1st argument is equal to or greater than the value of 10}}
44+
__buf_size_arg_constraint_concrete(buf); // expected-note {{Assuming the size of the 1st argument to '__buf_size_arg_constraint_concrete' is equal to or greater than 10}}
4545
clang_analyzer_eval(clang_analyzer_getExtent(buf) >= 10); // expected-warning{{TRUE}} \
4646
// expected-note{{TRUE}}
4747

clang/test/Analysis/std-c-library-functions-arg-constraints-notes.cpp

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
int __not_null(int *);
1616
void test_not_null(int *x) {
1717
__not_null(nullptr); // \
18-
// expected-note{{The 1st argument should not be NULL}} \
19-
// expected-warning{{}}
18+
// expected-warning{{The 1st argument to '__not_null' should not be NULL}}
2019
}
2120

2221
// Check the BufferSizeConstraint violation notes.
@@ -29,66 +28,159 @@ void test_buffer_size(int x) {
2928
case 1: {
3029
char buf[9];
3130
__buf_size_arg_constraint_concrete(buf); // \
32-
// expected-note{{The size of the 1st argument should be equal to or greater than the value of 10}} \
33-
// expected-warning{{}}
31+
// expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint_concrete' should be equal to or greater than 10}}
3432
break;
3533
}
3634
case 2: {
3735
char buf[3];
3836
__buf_size_arg_constraint(buf, 4); // \
39-
// expected-note{{The size of the 1st argument should be equal to or greater than the value of the 2nd arg}} \
40-
// expected-warning{{}}
37+
// expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}}
4138
break;
4239
}
4340
case 3: {
4441
char buf[3];
4542
__buf_size_arg_constraint_mul(buf, 4, 2); // \
46-
// expected-note{{The size of the 1st argument should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
47-
// expected-warning{{}}
43+
// expected-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
4844
break;
4945
}
5046
}
5147
}
5248

5349
// Check the RangeConstraint violation notes.
54-
int __single_val_1(int); // [1, 1]
55-
int __range_1_2(int); // [1, 2]
56-
int __range_1_2__4_5(int); // [1, 2], [4, 5]
57-
void test_range(int x) {
58-
__single_val_1(2); // \
59-
// expected-note{{The 1st argument should be within the range [1, 1]}} \
60-
// expected-warning{{}}
61-
}
62-
// Do more specific check against the range strings.
50+
51+
int __single_val_0(int); // [0, 0]
52+
int __single_val_1(int); // [1, 1]
53+
int __range_1_2(int); // [1, 2]
54+
int __range_m1_1(int); // [-1, 1]
55+
int __range_m2_m1(int); // [-2, -1]
56+
int __range_m10_10(int); // [-10, 10]
57+
int __range_m1_inf(int); // [-1, inf]
58+
int __range_0_inf(int); // [0, inf]
59+
int __range_1_inf(int); // [1, inf]
60+
int __range_minf_m1(int); // [-inf, -1]
61+
int __range_minf_0(int); // [-inf, 0]
62+
int __range_minf_1(int); // [-inf, 1]
63+
int __range_1_2__4_6(int); // [1, 2], [4, 6]
64+
int __range_1_2__4_inf(int); // [1, 2], [4, inf]
65+
66+
int __single_val_out_0(int); // [0, 0]
67+
int __single_val_out_1(int); // [1, 1]
68+
int __range_out_1_2(int); // [1, 2]
69+
int __range_out_m1_1(int); // [-1, 1]
70+
int __range_out_m2_m1(int); // [-2, -1]
71+
int __range_out_m10_10(int); // [-10, 10]
72+
int __range_out_m1_inf(int); // [-1, inf]
73+
int __range_out_0_inf(int); // [0, inf]
74+
int __range_out_1_inf(int); // [1, inf]
75+
int __range_out_minf_m1(int); // [-inf, -1]
76+
int __range_out_minf_0(int); // [-inf, 0]
77+
int __range_out_minf_1(int); // [-inf, 1]
78+
int __range_out_1_2__4_6(int); // [1, 2], [4, 6]
79+
int __range_out_1_2__4_inf(int); // [1, 2], [4, inf]
80+
6381
void test_range_values(int x) {
6482
switch (x) {
65-
case 1:
66-
__single_val_1(2); // expected-note{{[1, 1]}} \
67-
// expected-warning{{}}
68-
break;
69-
case 2:
70-
__range_1_2(3); // expected-note{{[1, 2]}} \
71-
// expected-warning{{}}
72-
break;
73-
case 3:
74-
__range_1_2__4_5(3); // expected-note{{[[1, 2], [4, 5]]}} \
75-
// expected-warning{{}}
76-
break;
83+
case 0:
84+
__single_val_0(1); // expected-warning{{should be zero}}
85+
break;
86+
case 1:
87+
__single_val_1(2); // expected-warning{{should be 1}}
88+
break;
89+
case 2:
90+
__range_1_2(3); // expected-warning{{should be 1 or 2}}
91+
break;
92+
case 3:
93+
__range_m1_1(3); // expected-warning{{should be between -1 and 1}}
94+
break;
95+
case 4:
96+
__range_m2_m1(1); // expected-warning{{should be -2 or -1}}
97+
break;
98+
case 5:
99+
__range_m10_10(11); // expected-warning{{should be between -10 and 10}}
100+
break;
101+
case 6:
102+
__range_m10_10(-11); // expected-warning{{should be between -10 and 10}}
103+
break;
104+
case 7:
105+
__range_1_2__4_6(3); // expected-warning{{should be 1 or 2 or 4, 5 or 6}}
106+
break;
107+
case 8:
108+
__range_1_2__4_inf(3); // expected-warning{{should be 1 or 2 or >= 4}}
109+
break;
77110
}
78111
}
79-
// Do more specific check against the range kinds.
80-
int __within(int); // [1, 1]
81-
int __out_of(int); // [1, 1]
82-
void test_range_kind(int x) {
112+
113+
void test_range_values_inf(int x) {
83114
switch (x) {
84-
case 1:
85-
__within(2); // expected-note{{within}} \
86-
// expected-warning{{}}
87-
break;
88-
case 2:
89-
__out_of(1); // expected-note{{out of}} \
90-
// expected-warning{{}}
91-
break;
115+
case 1:
116+
__range_m1_inf(-2); // expected-warning{{should be >= -1}}
117+
break;
118+
case 2:
119+
__range_0_inf(-1); // expected-warning{{should be >= 0}}
120+
break;
121+
case 3:
122+
__range_1_inf(0); // expected-warning{{should be > 0}}
123+
break;
124+
case 4:
125+
__range_minf_m1(0); // expected-warning{{should be < 0}}
126+
break;
127+
case 5:
128+
__range_minf_0(1); // expected-warning{{should be <= 0}}
129+
break;
130+
case 6:
131+
__range_minf_1(2); // expected-warning{{should be <= 1}}
132+
break;
92133
}
93134
}
94135

136+
void test_range_values_out(int x) {
137+
switch (x) {
138+
case 0:
139+
__single_val_out_0(0); // expected-warning{{should be nonzero}}
140+
break;
141+
case 1:
142+
__single_val_out_1(1); // expected-warning{{should be not equal to 1}}
143+
break;
144+
case 2:
145+
__range_out_1_2(2); // expected-warning{{should be not 1 and not 2}}
146+
break;
147+
case 3:
148+
__range_out_m1_1(-1); // expected-warning{{should be not between -1 and 1}}
149+
break;
150+
case 4:
151+
__range_out_m2_m1(-2); // expected-warning{{should be not -2 and not -1}}
152+
break;
153+
case 5:
154+
__range_out_m10_10(0); // expected-warning{{should be not between -10 and 10}}
155+
break;
156+
case 6:
157+
__range_out_1_2__4_6(1); // expected-warning{{should be not 1 and not 2 and not between 4 and 6}}
158+
break;
159+
case 7:
160+
__range_out_1_2__4_inf(4); // expected-warning{{should be not 1 and not 2 and < 4}}
161+
break;
162+
}
163+
}
164+
165+
void test_range_values_out_inf(int x) {
166+
switch (x) {
167+
case 1:
168+
__range_out_minf_m1(-1); // expected-warning{{should be >= 0}}
169+
break;
170+
case 2:
171+
__range_out_minf_0(0); // expected-warning{{should be > 0}}
172+
break;
173+
case 3:
174+
__range_out_minf_1(1); // expected-warning{{should be > 1}}
175+
break;
176+
case 4:
177+
__range_out_m1_inf(-1); // expected-warning{{should be < -1}}
178+
break;
179+
case 5:
180+
__range_out_0_inf(0); // expected-warning{{should be < 0}}
181+
break;
182+
case 6:
183+
__range_out_1_inf(1); // expected-warning{{should be <= 0}}
184+
break;
185+
}
186+
}

clang/test/Analysis/std-c-library-functions-arg-constraints-tracking-notes.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ void test_buf_size_concrete(void) {
1616
char buf[3]; // bugpath-note{{'buf' initialized here}}
1717
int s = 4; // bugpath-note{{'s' initialized to 4}}
1818
__buf_size_arg_constraint(buf, s); // \
19-
// bugpath-warning{{Function argument constraint is not satisfied}} \
20-
// bugpath-note{{}} \
21-
// bugpath-note{{Function argument constraint is not satisfied}}
19+
// bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}} \
20+
// bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint' should be equal to or greater than the value of the 2nd argument}}
2221
}
2322

2423
int __buf_size_arg_constraint_mul(const void *, size_t, size_t);
@@ -27,7 +26,6 @@ void test_buf_size_concrete_with_multiplication(void) {
2726
int s1 = 4; // bugpath-note{{'s1' initialized to 4}}
2827
int s2 = sizeof(short); // bugpath-note{{'s2' initialized to}}
2928
__buf_size_arg_constraint_mul(buf, s1, s2); // \
30-
// bugpath-warning{{Function argument constraint is not satisfied}} \
31-
// bugpath-note{{}} \
32-
// bugpath-note{{Function argument constraint is not satisfied}}
29+
// bugpath-warning{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}} \
30+
// bugpath-note{{The size of the 1st argument to '__buf_size_arg_constraint_mul' should be equal to or greater than the value of the 2nd argument times the 3rd argument}}
3331
}

0 commit comments

Comments
 (0)