1 // RUN: %clang_analyze_cc1 -w -analyzer-checker=debug.DumpLiveExprs %s 2>&1\
2 // RUN:   | FileCheck %s
3 
4 int coin();
5 
6 
testThatDumperWorks(int x,int y,int z)7 int testThatDumperWorks(int x, int y, int z) {
8   return x ? y : z;
9 }
10 
11 // [B5 (ENTRY)]
12 //    |
13 //    V
14 // [B4 (x)] ? [B2 (y)] : [B3 (z)]
15 //                \        /
16 //                 ---|----
17 //                    V
18 //                   [B1] --> [B0 (EXIT)]
19 //                  return
20 
21 // CHECK: [ B0 (live expressions at block exit) ]
22 // CHECK-EMPTY:
23 // CHECK-EMPTY:
24 // CHECK: [ B1 (live expressions at block exit) ]
25 // CHECK-EMPTY:
26 // CHECK-EMPTY:
27 // CHECK: [ B2 (live expressions at block exit) ]
28 // CHECK-EMPTY:
29 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int'
30 // CHECK-EMPTY:
31 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int'
32 // CHECK-EMPTY:
33 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean>
34 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue>
35 // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int'
36 // CHECK-EMPTY:
37 // CHECK-EMPTY:
38 // CHECK: [ B3 (live expressions at block exit) ]
39 // CHECK-EMPTY:
40 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int'
41 // CHECK-EMPTY:
42 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int'
43 // CHECK-EMPTY:
44 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean>
45 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue>
46 // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int'
47 // CHECK: [ B4 (live expressions at block exit) ]
48 // CHECK-EMPTY:
49 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int'
50 // CHECK-EMPTY:
51 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int'
52 // CHECK-EMPTY:
53 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean>
54 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue>
55 // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int'
56 // CHECK-EMPTY:
57 // CHECK-EMPTY:
58 // CHECK: [ B5 (live expressions at block exit) ]
59 // CHECK-EMPTY:
60 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int'
61 // CHECK-EMPTY:
62 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int'
63 // CHECK-EMPTY:
64 // CHECK-EMPTY:
65 
66 
testIfBranchExpression(bool flag)67 void testIfBranchExpression(bool flag) {
68   // No expressions should be carried over from one block to another here.
69   while (flag) {
70     int e = 1;
71     if (true)
72       e;
73   }
74 }
75 // CHECK: [ B0 (live expressions at block exit) ]
76 // CHECK-EMPTY:
77 // CHECK-EMPTY:
78 // CHECK: [ B1 (live expressions at block exit) ]
79 // CHECK-EMPTY:
80 // CHECK-EMPTY:
81 // CHECK: [ B2 (live expressions at block exit) ]
82 // CHECK-EMPTY:
83 // CHECK-EMPTY:
84 // CHECK: [ B3 (live expressions at block exit) ]
85 // CHECK-EMPTY:
86 // CHECK-EMPTY:
87 // CHECK: [ B4 (live expressions at block exit) ]
88 // CHECK-EMPTY:
89 // CHECK-EMPTY:
90 // CHECK: [ B5 (live expressions at block exit) ]
91 // CHECK-EMPTY:
92 // CHECK-EMPTY:
93 
94 
testWhileBodyExpression(bool flag)95 void testWhileBodyExpression(bool flag) {
96   // No expressions should be carried over from one block to another here.
97   while (flag) {
98     int e = 1;
99     while (coin())
100       e;
101   }
102 }
103 // CHECK: [ B0 (live expressions at block exit) ]
104 // CHECK-EMPTY:
105 // CHECK-EMPTY:
106 // CHECK: [ B1 (live expressions at block exit) ]
107 // CHECK-EMPTY:
108 // CHECK-EMPTY:
109 // CHECK: [ B2 (live expressions at block exit) ]
110 // CHECK-EMPTY:
111 // CHECK-EMPTY:
112 // CHECK: [ B3 (live expressions at block exit) ]
113 // CHECK-EMPTY:
114 // CHECK-EMPTY:
115 // CHECK: [ B4 (live expressions at block exit) ]
116 // CHECK-EMPTY:
117 // CHECK-EMPTY:
118 // CHECK: [ B5 (live expressions at block exit) ]
119 // CHECK-EMPTY:
120 // CHECK-EMPTY:
121 
122 
testDoWhileBodyExpression(bool flag)123 void testDoWhileBodyExpression(bool flag) {
124   // No expressions should be carried over from one block to another here.
125   while (flag) {
126     int e = 1;
127     do
128       e;
129     while (coin());
130   }
131 }
132 // CHECK: [ B0 (live expressions at block exit) ]
133 // CHECK-EMPTY:
134 // CHECK-EMPTY:
135 // CHECK: [ B1 (live expressions at block exit) ]
136 // CHECK-EMPTY:
137 // CHECK-EMPTY:
138 // CHECK: [ B2 (live expressions at block exit) ]
139 // CHECK-EMPTY:
140 // CHECK-EMPTY:
141 // CHECK: [ B3 (live expressions at block exit) ]
142 // CHECK-EMPTY:
143 // CHECK-EMPTY:
144 // CHECK: [ B4 (live expressions at block exit) ]
145 // CHECK-EMPTY:
146 // CHECK-EMPTY:
147 // CHECK: [ B5 (live expressions at block exit) ]
148 // CHECK-EMPTY:
149 // CHECK-EMPTY:
150 
151 
testForBodyExpression(bool flag)152 void testForBodyExpression(bool flag) {
153   // No expressions should be carried over from one block to another here.
154   while (flag) {
155     int e = 1;
156     for (; coin();)
157       e;
158   }
159 }
160 // CHECK: [ B0 (live expressions at block exit) ]
161 // CHECK-EMPTY:
162 // CHECK-EMPTY:
163 // CHECK: [ B1 (live expressions at block exit) ]
164 // CHECK-EMPTY:
165 // CHECK-EMPTY:
166 // CHECK: [ B2 (live expressions at block exit) ]
167 // CHECK-EMPTY:
168 // CHECK-EMPTY:
169 // CHECK: [ B3 (live expressions at block exit) ]
170 // CHECK-EMPTY:
171 // CHECK-EMPTY:
172 // CHECK: [ B4 (live expressions at block exit) ]
173 // CHECK-EMPTY:
174 // CHECK-EMPTY:
175 // CHECK: [ B5 (live expressions at block exit) ]
176 // CHECK-EMPTY:
177 // CHECK-EMPTY:
178 
179 void clang_analyzer_eval(bool);
180 
test_lambda_refcapture()181 void test_lambda_refcapture() {
182   int a = 6;
183   [&](int &a) { a = 42; }(a);
184   clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
185 }
186 
187 // CHECK: [ B0 (live expressions at block exit) ]
188 // CHECK-EMPTY:
189 // CHECK-EMPTY:
190 // CHECK-NEXT: [ B1 (live expressions at block exit) ]
191 // CHECK-EMPTY:
192 // CHECK-EMPTY:
193 // CHECK-NEXT: [ B2 (live expressions at block exit) ]
194 // CHECK-EMPTY:
195 // CHECK-EMPTY:
196