164 lines · cpp
1// RUN: %clang_analyze_cc1 %s \2// RUN: -analyzer-checker=core \3// RUN: -analyzer-checker=debug.ExprInspection \4// RUN: -analyzer-config eagerly-assume=false \5// RUN: -verify6 7void clang_analyzer_eval(bool);8void clang_analyzer_warnIfReached();9 10int test_legacy_behavior(int x, int y) {11 if (y != 0)12 return 0;13 if (x + y != 0)14 return 0;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}}18}19 20int test_rhs_further_constrained(int x, int y) {21 if (x + y != 0)22 return 0;23 if (y != 0)24 return 0;25 clang_analyzer_eval(x + y == 0); // expected-warning{{TRUE}}26 clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}27 return 0;28}29 30int test_lhs_further_constrained(int x, int y) {31 if (x + y != 0)32 return 0;33 if (x != 0)34 return 0;35 clang_analyzer_eval(x + y == 0); // expected-warning{{TRUE}}36 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}37 return 0;38}39 40int test_lhs_and_rhs_further_constrained(int x, int y) {41 if (x % y != 1)42 return 0;43 if (x != 1)44 return 0;45 if (y != 2)46 return 0;47 clang_analyzer_eval(x % y == 1); // expected-warning{{TRUE}}48 clang_analyzer_eval(y == 2); // expected-warning{{TRUE}}49 return 0;50}51 52int test_commutativity(int x, int y) {53 if (x + y != 0)54 return 0;55 if (y != 0)56 return 0;57 clang_analyzer_eval(y + x == 0); // expected-warning{{TRUE}}58 clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}59 return 0;60}61 62int test_binop_when_height_is_2_r(int a, int x, int y, int z) {63 switch (a) {64 case 1: {65 if (x + y + z != 0)66 return 0;67 if (z != 0)68 return 0;69 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}}70 clang_analyzer_eval(z == 0); // expected-warning{{TRUE}}71 break;72 }73 case 2: {74 if (x + y + z != 0)75 return 0;76 if (y != 0)77 return 0;78 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}}79 clang_analyzer_eval(y == 0); // expected-warning{{TRUE}}80 break;81 }82 case 3: {83 if (x + y + z != 0)84 return 0;85 if (x != 0)86 return 0;87 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}}88 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}89 break;90 }91 case 4: {92 if (x + y + z != 0)93 return 0;94 if (x + y != 0)95 return 0;96 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}}97 clang_analyzer_eval(x + y == 0); // expected-warning{{TRUE}}98 break;99 }100 case 5: {101 if (z != 0)102 return 0;103 if (x + y + z != 0)104 return 0;105 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}}106 if (y != 0)107 return 0;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}}111 break;112 }113 114 }115 return 0;116}117 118void test_equivalence_classes_are_updated(int a, int b, int c, int d) {119 if (a + b != c)120 return;121 if (a != d)122 return;123 if (b != 0)124 return;125 clang_analyzer_eval(c == d); // expected-warning{{TRUE}}126 // Keep the symbols and the constraints! alive.127 (void)(a * b * c * d);128 return;129}130 131void test_contradiction(int a, int b, int c, int d) {132 if (a + b != c)133 return;134 if (a == c)135 return;136 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}137 138 // Bring in the contradiction.139 if (b != 0)140 return;141 clang_analyzer_warnIfReached(); // no-warning, i.e. UNREACHABLE142 // Keep the symbols and the constraints! alive.143 (void)(a * b * c * d);144 return;145}146 147void test_deferred_contradiction(int e0, int b0, int b1) {148 149 int e1 = e0 - b0; // e1 is bound to (reg_$0<int e0>) - (reg_$1<int b0>)150 (void)(b0 == 2); // bifurcate151 152 int e2 = e1 - b1;153 if (e2 > 0) { // b1 != e1154 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}155 // Here, e1 is still bound to (reg_$0<int e0>) - (reg_$1<int b0>) but we156 // should be able to simplify it to (reg_$0<int e0>) - 2 and thus realize157 // the contradiction.158 if (b1 == e1) {159 clang_analyzer_warnIfReached(); // no-warning, i.e. UNREACHABLE160 (void)(b0 * b1 * e0 * e1 * e2);161 }162 }163}164