1 | // RUN: %clang_analyze_cc1 -std=c99 -Dbool=_Bool -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s |
2 | // RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s |
3 | |
4 | int var; |
5 | |
6 | void err_eq(int x) { |
7 | var = 77 / x; // expected-note {{Division with compared value made here}} |
8 | if (x == 0) { } // expected-warning {{Value being compared against zero has already been used for division}} |
9 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
10 | |
11 | void err_eq2(int x) { |
12 | var = 77 / x; // expected-note {{Division with compared value made here}} |
13 | if (0 == x) { } // expected-warning {{Value being compared against zero has already been used for division}} |
14 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
15 | |
16 | void err_ne(int x) { |
17 | var = 77 / x; // expected-note {{Division with compared value made here}} |
18 | if (x != 0) { } // expected-warning {{Value being compared against zero has already been used for division}} |
19 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
20 | |
21 | void err_ge(int x) { |
22 | var = 77 / x; // expected-note {{Division with compared value made here}} |
23 | if (x >= 0) { } // expected-warning {{Value being compared against zero has already been used for division}} |
24 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
25 | |
26 | void err_le(int x) { |
27 | var = 77 / x; // expected-note {{Division with compared value made here}} |
28 | if (x <= 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
29 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
30 | |
31 | void err_yes(int x) { |
32 | var = 77 / x; // expected-note {{Division with compared value made here}} |
33 | if (x) {} // expected-warning {{Value being compared against zero has already been used for division}} |
34 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
35 | void err_not(int x) { |
36 | var = 77 / x; // expected-note {{Division with compared value made here}} |
37 | if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}} |
38 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
39 | |
40 | void err_pnot(int x) { |
41 | int *y = &x; |
42 | var = 77 / *y; // expected-note {{Division with compared value made here}} |
43 | if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}} |
44 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
45 | |
46 | void err_pnot2(int x) { |
47 | int *y = &x; |
48 | var = 77 / x; // expected-note {{Division with compared value made here}} |
49 | if (!*y) {} // expected-warning {{Value being compared against zero has already been used for division}} |
50 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
51 | |
52 | void err_ppnot(int x) { |
53 | int *y = &x; |
54 | int **z = &y; |
55 | var = 77 / **z; // expected-note {{Division with compared value made here}} |
56 | if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}} |
57 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
58 | |
59 | void err_orig_checker(int x) { |
60 | if (x != 0) // expected-note {{Assuming 'x' is equal to 0}} expected-note {{Taking false branch}} |
61 | return; |
62 | var = 77 / x; // expected-warning {{Division by zero}} expected-note {{Division by zero}} |
63 | if (!x) {} // no-warning |
64 | } |
65 | |
66 | void ok_other(int x, int y) { |
67 | var = 77 / y; |
68 | if (x == 0) { |
69 | } |
70 | } |
71 | |
72 | void ok_assign(int x) { |
73 | var = 77 / x; |
74 | x = var / 77; // <- assignment => don't warn |
75 | if (x == 0) { |
76 | } |
77 | } |
78 | |
79 | void ok_assign2(int x) { |
80 | var = 77 / x; |
81 | x = var / 77; // <- assignment => don't warn |
82 | if (0 == x) { |
83 | } |
84 | } |
85 | |
86 | void ok_dec(int x) { |
87 | var = 77 / x; |
88 | x--; // <- assignment => don't warn |
89 | if (x == 0) { |
90 | } |
91 | } |
92 | |
93 | void ok_inc(int x) { |
94 | var = 77 / x; |
95 | x++; // <- assignment => don't warn |
96 | if (x == 0) { |
97 | } |
98 | } |
99 | |
100 | void do_something_ptr(int *x); |
101 | void ok_callfunc_ptr(int x) { |
102 | var = 77 / x; |
103 | do_something_ptr(&x); // <- pass address of x to function => don't warn |
104 | if (x == 0) { |
105 | } |
106 | } |
107 | |
108 | void do_something(int x); |
109 | void nok_callfunc(int x) { |
110 | var = 77 / x; // expected-note {{Division with compared value made here}} |
111 | do_something(x); |
112 | if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
113 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
114 | |
115 | void ok_if(int x) { |
116 | if (x > 3) |
117 | var = 77 / x; |
118 | if (x == 0) { |
119 | } |
120 | } |
121 | |
122 | void ok_if2(int x) { |
123 | if (x < 3) |
124 | var = 77 / x; |
125 | if (x == 0) { |
126 | } // TODO warn here |
127 | } |
128 | |
129 | void ok_pif(int x) { |
130 | int *y = &x; |
131 | if (x < 3) |
132 | var = 77 / *y; |
133 | if (x == 0) { |
134 | } // TODO warn here |
135 | } |
136 | |
137 | int getValue(bool *isPositive); |
138 | void use(int a); |
139 | void foo() { |
140 | bool isPositive; |
141 | int x = getValue(&isPositive); |
142 | if (isPositive) { |
143 | use(5 / x); |
144 | } |
145 | |
146 | if (x == 0) { |
147 | } |
148 | } |
149 | |
150 | int getValue2(); |
151 | void foo2() { |
152 | int x = getValue2(); |
153 | int y = x; |
154 | |
155 | use(5 / x); // expected-note {{Division with compared value made here}} |
156 | if (y == 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
157 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
158 | |
159 | void ok_while(int x) { |
160 | int n = 100 / x; |
161 | while (x != 0) { // <- do not warn |
162 | x--; |
163 | } |
164 | } |
165 | |
166 | void err_not2(int x, int y) { |
167 | int v; |
168 | var = 77 / x; |
169 | |
170 | if (y) |
171 | v = 0; |
172 | |
173 | if (!x) { |
174 | } // TODO warn here |
175 | } |
176 | |
177 | inline void inline_func(int x) { |
178 | var = 77 / x; // expected-note {{Division with compared value made here}} |
179 | if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
180 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
181 | |
182 | void err_inline(int x) { |
183 | var = 77 / x; |
184 | inline_func(x); // expected-note {{Calling 'inline_func'}} |
185 | if (x == 0) { |
186 | } |
187 | } |
188 | |
189 | inline void inline_func2(int x) {} |
190 | |
191 | void err_inline2(int x) { |
192 | var = 77 / x; // expected-note {{Division with compared value made here}} |
193 | inline_func2(x); |
194 | if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
195 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
196 | |
197 | inline void inline_func3(int x) { |
198 | var = 77 / x; |
199 | } |
200 | void ok_inline(int x) { |
201 | var = 77 / x; // expected-note {{Division with compared value made here}} |
202 | inline_func3(x); |
203 | if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}} |
204 | } // expected-note@-1 {{Value being compared against zero has already been used for division}} |
205 | |