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: -verify 6 7 // Here we test whether the SValBuilder is capable to simplify existing 8 // compound SVals (where there are at leaset 3 symbols in the tree) based on 9 // newly added constraints. 10 11 void clang_analyzer_eval(bool); 12 void clang_analyzer_warnIfReached(); 13 14 void test_left_tree_constrained(int x, int y, int z) { 15 if (x + y + z != 0) 16 return; 17 if (x + y != 0) 18 return; 19 clang_analyzer_eval(x + y + z == 0); // expected-warning{{TRUE}} 20 clang_analyzer_eval(x + y == 0); // expected-warning{{TRUE}} 21 clang_analyzer_eval(z == 0); // expected-warning{{TRUE}} 22 x = y = z = 1; 23 return; 24 } 25 26 void test_right_tree_constrained(int x, int y, int z) { 27 if (x + y * z != 0) 28 return; 29 if (y * z != 0) 30 return; 31 clang_analyzer_eval(x + y * z == 0); // expected-warning{{TRUE}} 32 clang_analyzer_eval(y * z == 0); // expected-warning{{TRUE}} 33 clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} 34 return; 35 } 36 37 void test_left_tree_constrained_minus(int x, int y, int z) { 38 if (x - y - z != 0) 39 return; 40 if (x - y != 0) 41 return; 42 clang_analyzer_eval(x - y - z == 0); // expected-warning{{TRUE}} 43 clang_analyzer_eval(x - y == 0); // expected-warning{{TRUE}} 44 clang_analyzer_eval(z == 0); // expected-warning{{TRUE}} 45 x = y = z = 1; 46 return; 47 } 48 49 void test_SymInt_constrained(int x, int y, int z) { 50 if (x * y * z != 4) 51 return; 52 if (z != 2) 53 return; 54 if (x * y == 3) { 55 clang_analyzer_warnIfReached(); // no-warning 56 return; 57 } 58 (void)(x * y * z); 59 } 60 61 void test_SValBuilder_simplifies_IntSym(int x, int y, int z) { 62 // Most IntSym BinOps are transformed to SymInt in SimpleSValBuilder. 63 // Division is one exception. 64 x = 77 / (y + z); 65 if (y + z != 1) 66 return; 67 clang_analyzer_eval(x == 77); // expected-warning{{TRUE}} 68 (void)(x * y * z); 69 } 70 71 void recurring_symbol(int b) { 72 if (b * b != b) 73 if ((b * b) * b * b != (b * b) * b) 74 if (b * b == 1) // no-crash (assert should not fire) 75 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 76 } 77