xref: /llvm-project/clang/test/Analysis/symbol-simplification-fixpoint-two-iterations.cpp (revision 648e256e541d6421eca72df733f888787485bda8)
1 // RUN: %clang_analyze_cc1 %s \
2 // RUN:   -analyzer-checker=core \
3 // RUN:   -analyzer-checker=debug.ExprInspection \
4 // RUN:   2>&1 | FileCheck %s
5 
6 // In this test we check whether the solver's symbol simplification mechanism
7 // is capable of reaching a fixpoint. This should be done after TWO iterations.
8 
9 void clang_analyzer_printState();
10 
11 void test(int a, int b, int c, int d) {
12   if (a + b + c != d)
13     return;
14   if (c + b != 0)
15     return;
16   clang_analyzer_printState();
17   // CHECK:      "constraints": [
18   // CHECK-NEXT:   { "symbol": "(((reg_$0<int a>) + (reg_$2<int b>)) + (reg_$5<int c>)) != (reg_$8<int d>)", "range": "{ [0, 0] }" },
19   // CHECK-NEXT:   { "symbol": "(reg_$5<int c>) + (reg_$2<int b>)", "range": "{ [0, 0] }" }
20   // CHECK-NEXT: ],
21   // CHECK-NEXT: "equivalence_classes": [
22   // CHECK-NEXT:   [ "((reg_$0<int a>) + (reg_$2<int b>)) + (reg_$5<int c>)", "reg_$8<int d>" ]
23   // CHECK-NEXT: ],
24   // CHECK-NEXT: "disequality_info": null,
25 
26   // Simplification starts here.
27   if (b != 0)
28     return;
29   clang_analyzer_printState();
30   // CHECK:       "constraints": [
31   // CHECK-NEXT:    { "symbol": "(reg_$0<int a>) != (reg_$8<int d>)", "range": "{ [0, 0] }" },
32   // CHECK-NEXT:    { "symbol": "reg_$2<int b>", "range": "{ [0, 0] }" },
33   // CHECK-NEXT:    { "symbol": "reg_$5<int c>", "range": "{ [0, 0] }" }
34   // CHECK-NEXT:  ],
35   // CHECK-NEXT:  "equivalence_classes": [
36   // CHECK-NEXT:    [ "(reg_$0<int a>) != (reg_$8<int d>)" ],
37   // CHECK-NEXT:    [ "reg_$0<int a>", "reg_$8<int d>" ],
38   // CHECK-NEXT:    [ "reg_$5<int c>" ]
39   // CHECK-NEXT:  ],
40   // CHECK-NEXT:  "disequality_info": null,
41 
42   // Keep the symbols and the constraints! alive.
43   (void)(a * b * c * d);
44   return;
45 }
46