1// RUN: %clang_cc1 -std=c99 -Dbool=_Bool -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
2// RUN: %clang_cc1 -x c++ -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
3
4int var;
5
6void 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
11void 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
16void 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
21void 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
26void 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
31void 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}}
35void 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
40void 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
46void 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
52void 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
59void 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
66void ok_other(int x, int y) {
67  var = 77 / y;
68  if (x == 0) {
69  }
70}
71
72void ok_assign(int x) {
73  var = 77 / x;
74  x = var / 77; // <- assignment => don't warn
75  if (x == 0) {
76  }
77}
78
79void ok_assign2(int x) {
80  var = 77 / x;
81  x = var / 77; // <- assignment => don't warn
82  if (0 == x) {
83  }
84}
85
86void ok_dec(int x) {
87  var = 77 / x;
88  x--; // <- assignment => don't warn
89  if (x == 0) {
90  }
91}
92
93void ok_inc(int x) {
94  var = 77 / x;
95  x++; // <- assignment => don't warn
96  if (x == 0) {
97  }
98}
99
100void do_something_ptr(int *x);
101void 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
108void do_something(int x);
109void 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
115void ok_if(int x) {
116  if (x > 3)
117    var = 77 / x;
118  if (x == 0) {
119  }
120}
121
122void ok_if2(int x) {
123  if (x < 3)
124    var = 77 / x;
125  if (x == 0) {
126  } // TODO warn here
127}
128
129void 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
137int getValue(bool *isPositive);
138void use(int a);
139void 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
150int getValue2();
151void 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
159void ok_while(int x) {
160  int n = 100 / x;
161  while (x != 0) { // <- do not warn
162    x--;
163  }
164}
165
166void 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
177inline 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
182void err_inline(int x) {
183  var = 77 / x;
184  inline_func(x); // expected-note {{Calling 'inline_func'}}
185  if (x == 0) {
186  }
187}
188
189inline void inline_func2(int x) {}
190
191void 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
197inline void inline_func3(int x) {
198  var = 77 / x;
199}
200void 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