1 // RUN: %clang_analyze_cc1 %s \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=debug.ExprInspection \
4 // RUN: -analyzer-config eagerly-assume=false \
7 void clang_analyzer_eval(bool);
8 void clang_analyzer_warnIfReached();
10 int test_legacy_behavior(int x
, int y
) {
15 clang_analyzer_eval(x
+ y
== 0); // expected-warning{{TRUE}}
16 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
17 return y
/ (x
+ y
); // expected-warning{{Division by zero}}
20 int test_rhs_further_constrained(int x
, int y
) {
25 clang_analyzer_eval(x
+ y
== 0); // expected-warning{{TRUE}}
26 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
30 int test_lhs_further_constrained(int x
, int y
) {
35 clang_analyzer_eval(x
+ y
== 0); // expected-warning{{TRUE}}
36 clang_analyzer_eval(x
== 0); // expected-warning{{TRUE}}
40 int test_lhs_and_rhs_further_constrained(int x
, int y
) {
47 clang_analyzer_eval(x
% y
== 1); // expected-warning{{TRUE}}
48 clang_analyzer_eval(y
== 2); // expected-warning{{TRUE}}
52 int test_commutativity(int x
, int y
) {
57 clang_analyzer_eval(y
+ x
== 0); // expected-warning{{TRUE}}
58 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
62 int test_binop_when_height_is_2_r(int a
, int x
, int y
, int z
) {
69 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
70 clang_analyzer_eval(z
== 0); // expected-warning{{TRUE}}
78 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
79 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
87 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
88 clang_analyzer_eval(x
== 0); // expected-warning{{TRUE}}
96 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
97 clang_analyzer_eval(x
+ y
== 0); // expected-warning{{TRUE}}
105 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
108 clang_analyzer_eval(y
== 0); // expected-warning{{TRUE}}
109 clang_analyzer_eval(z
== 0); // expected-warning{{TRUE}}
110 clang_analyzer_eval(x
+ y
+ z
== 0); // expected-warning{{TRUE}}
118 void test_equivalence_classes_are_updated(int a
, int b
, int c
, int d
) {
125 clang_analyzer_eval(c
== d
); // expected-warning{{TRUE}}
126 // Keep the symbols and the constraints! alive.
127 (void)(a
* b
* c
* d
);
131 void test_contradiction(int a
, int b
, int c
, int d
) {
136 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
138 // Bring in the contradiction.
141 clang_analyzer_warnIfReached(); // no-warning, i.e. UNREACHABLE
142 // Keep the symbols and the constraints! alive.
143 (void)(a
* b
* c
* d
);
147 void test_deferred_contradiction(int e0
, int b0
, int b1
) {
149 int e1
= e0
- b0
; // e1 is bound to (reg_$0<int e0>) - (reg_$1<int b0>)
150 (void)(b0
== 2); // bifurcate
153 if (e2
> 0) { // b1 != e1
154 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
155 // Here, e1 is still bound to (reg_$0<int e0>) - (reg_$1<int b0>) but we
156 // should be able to simplify it to (reg_$0<int e0>) - 2 and thus realize
157 // the contradiction.
159 clang_analyzer_warnIfReached(); // no-warning, i.e. UNREACHABLE
160 (void)(b0
* b1
* e0
* e1
* e2
);