xref: /llvm-project/clang/test/Analysis/svalbuilder-simplify-compound-svals.cpp (revision 0a17896fe6fdbbde1f9d3ffbb10a4f3bfa8960f9)
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 
test_left_tree_constrained(int x,int y,int z)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 
test_right_tree_constrained(int x,int y,int z)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 
test_left_tree_constrained_minus(int x,int y,int z)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 
test_SymInt_constrained(int x,int y,int z)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 
test_SValBuilder_simplifies_IntSym(int x,int y,int z)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 
recurring_symbol(int b)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