xref: /llvm-project/clang/test/Analysis/array-init-loop.cpp (revision a917ae0b4fc0d792ee0e2c512c4ea539f98e1204)
18ef62808Sisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify %s
28ef62808Sisuckatcs 
38ef62808Sisuckatcs void clang_analyzer_eval(bool);
48ef62808Sisuckatcs 
58ef62808Sisuckatcs void array_init() {
68ef62808Sisuckatcs   int arr[] = {1, 2, 3, 4, 5};
78ef62808Sisuckatcs 
88ef62808Sisuckatcs   auto [a, b, c, d, e] = arr;
98ef62808Sisuckatcs 
108ef62808Sisuckatcs   clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
118ef62808Sisuckatcs   clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
128ef62808Sisuckatcs   clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
138ef62808Sisuckatcs   clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
148ef62808Sisuckatcs   clang_analyzer_eval(e == 5); // expected-warning{{TRUE}}
158ef62808Sisuckatcs }
168ef62808Sisuckatcs 
178ef62808Sisuckatcs void array_uninit() {
188ef62808Sisuckatcs   int arr[5];
198ef62808Sisuckatcs 
208ef62808Sisuckatcs   auto [a, b, c, d, e] = arr;
218ef62808Sisuckatcs 
228ef62808Sisuckatcs   int x = e; // expected-warning{{Assigned value is garbage or undefined}}
238ef62808Sisuckatcs }
248ef62808Sisuckatcs 
258ef62808Sisuckatcs void lambda_init() {
268ef62808Sisuckatcs   int arr[] = {1, 2, 3, 4, 5};
278ef62808Sisuckatcs 
288ef62808Sisuckatcs   auto l = [arr] { return arr[0]; }();
298ef62808Sisuckatcs   clang_analyzer_eval(l == 1); // expected-warning{{TRUE}}
308ef62808Sisuckatcs 
318ef62808Sisuckatcs   l = [arr] { return arr[1]; }();
328ef62808Sisuckatcs   clang_analyzer_eval(l == 2); // expected-warning{{TRUE}}
338ef62808Sisuckatcs 
348ef62808Sisuckatcs   l = [arr] { return arr[2]; }();
358ef62808Sisuckatcs   clang_analyzer_eval(l == 3); // expected-warning{{TRUE}}
368ef62808Sisuckatcs 
378ef62808Sisuckatcs   l = [arr] { return arr[3]; }();
388ef62808Sisuckatcs   clang_analyzer_eval(l == 4); // expected-warning{{TRUE}}
398ef62808Sisuckatcs 
408ef62808Sisuckatcs   l = [arr] { return arr[4]; }();
418ef62808Sisuckatcs   clang_analyzer_eval(l == 5); // expected-warning{{TRUE}}
428ef62808Sisuckatcs }
438ef62808Sisuckatcs 
448ef62808Sisuckatcs void lambda_uninit() {
458ef62808Sisuckatcs   int arr[5];
468ef62808Sisuckatcs 
478ef62808Sisuckatcs   // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal
488ef62808Sisuckatcs   int l = [arr] { return arr[0]; }();
498ef62808Sisuckatcs   clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
508ef62808Sisuckatcs 
518ef62808Sisuckatcs   l = [arr] { return arr[1]; }();
528ef62808Sisuckatcs   clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
538ef62808Sisuckatcs 
548ef62808Sisuckatcs   l = [arr] { return arr[2]; }();
558ef62808Sisuckatcs   clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
568ef62808Sisuckatcs 
578ef62808Sisuckatcs   l = [arr] { return arr[3]; }();
588ef62808Sisuckatcs   clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
598ef62808Sisuckatcs 
608ef62808Sisuckatcs   l = [arr] { return arr[4]; }();
618ef62808Sisuckatcs   clang_analyzer_eval(l); // expected-warning{{UNKNOWN}}
628ef62808Sisuckatcs }
638ef62808Sisuckatcs 
648ef62808Sisuckatcs struct S {
658ef62808Sisuckatcs   int arr[5];
668ef62808Sisuckatcs };
678ef62808Sisuckatcs 
688ef62808Sisuckatcs void copy_ctor_init() {
698ef62808Sisuckatcs   S orig;
708ef62808Sisuckatcs   orig.arr[0] = 1;
718ef62808Sisuckatcs   orig.arr[1] = 2;
728ef62808Sisuckatcs   orig.arr[2] = 3;
738ef62808Sisuckatcs   orig.arr[3] = 4;
748ef62808Sisuckatcs   orig.arr[4] = 5;
758ef62808Sisuckatcs 
768ef62808Sisuckatcs   S copy = orig;
778ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[0] == 1); // expected-warning{{TRUE}}
788ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[1] == 2); // expected-warning{{TRUE}}
798ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[2] == 3); // expected-warning{{TRUE}}
808ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[3] == 4); // expected-warning{{TRUE}}
818ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[4] == 5); // expected-warning{{TRUE}}
828ef62808Sisuckatcs }
838ef62808Sisuckatcs 
848ef62808Sisuckatcs void copy_ctor_uninit() {
858ef62808Sisuckatcs   S orig;
868ef62808Sisuckatcs 
878ef62808Sisuckatcs   S copy = orig;
888ef62808Sisuckatcs 
898ef62808Sisuckatcs   // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.
908ef62808Sisuckatcs   // If the struct is not considered a small struct, instead of a copy, we store a lazy compound value.
918ef62808Sisuckatcs   // As the struct has an array data member, it is not considered small.
928ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[0]); // expected-warning{{UNKNOWN}}
938ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[1]); // expected-warning{{UNKNOWN}}
948ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[2]); // expected-warning{{UNKNOWN}}
958ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[3]); // expected-warning{{UNKNOWN}}
968ef62808Sisuckatcs   clang_analyzer_eval(copy.arr[4]); // expected-warning{{UNKNOWN}}
978ef62808Sisuckatcs }
988ef62808Sisuckatcs 
998ef62808Sisuckatcs void move_ctor_init() {
1008ef62808Sisuckatcs   S orig;
1018ef62808Sisuckatcs   orig.arr[0] = 1;
1028ef62808Sisuckatcs   orig.arr[1] = 2;
1038ef62808Sisuckatcs   orig.arr[2] = 3;
1048ef62808Sisuckatcs   orig.arr[3] = 4;
1058ef62808Sisuckatcs   orig.arr[4] = 5;
1068ef62808Sisuckatcs 
1078ef62808Sisuckatcs   S moved = (S &&) orig;
1088ef62808Sisuckatcs 
1098ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[0] == 1); // expected-warning{{TRUE}}
1108ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[1] == 2); // expected-warning{{TRUE}}
1118ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[2] == 3); // expected-warning{{TRUE}}
1128ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[3] == 4); // expected-warning{{TRUE}}
1138ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[4] == 5); // expected-warning{{TRUE}}
1148ef62808Sisuckatcs }
1158ef62808Sisuckatcs 
1168ef62808Sisuckatcs void move_ctor_uninit() {
1178ef62808Sisuckatcs   S orig;
1188ef62808Sisuckatcs 
1198ef62808Sisuckatcs   S moved = (S &&) orig;
1208ef62808Sisuckatcs 
1218ef62808Sisuckatcs   // FIXME: These should be Undefined, but we fail to read Undefined from a lazyCompoundVal.
1228ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[0]); // expected-warning{{UNKNOWN}}
1238ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[1]); // expected-warning{{UNKNOWN}}
1248ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[2]); // expected-warning{{UNKNOWN}}
1258ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[3]); // expected-warning{{UNKNOWN}}
1268ef62808Sisuckatcs   clang_analyzer_eval(moved.arr[4]); // expected-warning{{UNKNOWN}}
1278ef62808Sisuckatcs }
1288a13326dSisuckatcs 
1298a13326dSisuckatcs // The struct has a user defined copy and move ctor, which allow us to
1308a13326dSisuckatcs // track the values more precisely when an array of this struct is being
1318a13326dSisuckatcs // copy/move initialized by ArrayInitLoopExpr.
1328a13326dSisuckatcs struct S2 {
1338a13326dSisuckatcs   inline static int c = 0;
1348a13326dSisuckatcs   int i;
1358a13326dSisuckatcs 
1368a13326dSisuckatcs   S2() : i(++c) {}
1378a13326dSisuckatcs 
1388a13326dSisuckatcs   S2(const S2 &copy) {
1398a13326dSisuckatcs     i = copy.i + 1;
1408a13326dSisuckatcs   }
1418a13326dSisuckatcs 
1428a13326dSisuckatcs   S2(S2 &&move) {
1438a13326dSisuckatcs     i = move.i + 2;
1448a13326dSisuckatcs   }
1458a13326dSisuckatcs };
1468a13326dSisuckatcs 
1478a13326dSisuckatcs void array_init_non_pod() {
1488a13326dSisuckatcs   S2::c = 0;
1498a13326dSisuckatcs   S2 arr[4];
1508a13326dSisuckatcs 
1518a13326dSisuckatcs   auto [a, b, c, d] = arr;
1528a13326dSisuckatcs 
1538a13326dSisuckatcs   clang_analyzer_eval(a.i == 2); // expected-warning{{TRUE}}
1548a13326dSisuckatcs   clang_analyzer_eval(b.i == 3); // expected-warning{{TRUE}}
1558a13326dSisuckatcs   clang_analyzer_eval(c.i == 4); // expected-warning{{TRUE}}
1568a13326dSisuckatcs   clang_analyzer_eval(d.i == 5); // expected-warning{{TRUE}}
1578a13326dSisuckatcs }
1588a13326dSisuckatcs 
1598a13326dSisuckatcs struct S3 {
1608a13326dSisuckatcs   int i;
1618a13326dSisuckatcs };
1628a13326dSisuckatcs 
163996b092cSisuckatcs // The duplicate is required to emit a warning at 2 different places.
164996b092cSisuckatcs struct S3_duplicate {
165996b092cSisuckatcs   int i;
166996b092cSisuckatcs };
167996b092cSisuckatcs 
1688a13326dSisuckatcs void array_uninit_non_pod() {
1698a13326dSisuckatcs   S3 arr[1];
1708a13326dSisuckatcs 
1718a13326dSisuckatcs   auto [a] = arr; // expected-warning@159{{ in implicit constructor is garbage or undefined }}
1728a13326dSisuckatcs }
1738a13326dSisuckatcs 
1748a13326dSisuckatcs void lambda_init_non_pod() {
1758a13326dSisuckatcs   S2::c = 0;
1768a13326dSisuckatcs   S2 arr[4];
1778a13326dSisuckatcs 
1788a13326dSisuckatcs   auto l = [arr] { return arr[0].i; }();
179996b092cSisuckatcs   clang_analyzer_eval(l == 2); // expected-warning{{TRUE}}
1808a13326dSisuckatcs 
1818a13326dSisuckatcs   l = [arr] { return arr[1].i; }();
182996b092cSisuckatcs   clang_analyzer_eval(l == 3); // expected-warning{{TRUE}}
1838a13326dSisuckatcs 
1848a13326dSisuckatcs   l = [arr] { return arr[2].i; }();
185996b092cSisuckatcs   clang_analyzer_eval(l == 4); // expected-warning{{TRUE}}
1868a13326dSisuckatcs 
1878a13326dSisuckatcs   l = [arr] { return arr[3].i; }();
188996b092cSisuckatcs   clang_analyzer_eval(l == 5); // expected-warning{{TRUE}}
1898a13326dSisuckatcs }
1908a13326dSisuckatcs 
1918a13326dSisuckatcs void lambda_uninit_non_pod() {
192996b092cSisuckatcs   S3_duplicate arr[4];
1938a13326dSisuckatcs 
194996b092cSisuckatcs   int l = [arr] { return arr[3].i; }(); // expected-warning@164{{ in implicit constructor is garbage or undefined }}
1958a13326dSisuckatcs }
1968a13326dSisuckatcs 
1978a13326dSisuckatcs // If this struct is being copy/move constructed by the implicit ctors, ArrayInitLoopExpr
1988a13326dSisuckatcs // is responsible for the initialization of 'arr' by copy/move constructing each of the
1998a13326dSisuckatcs // elements.
2008a13326dSisuckatcs struct S5 {
2018a13326dSisuckatcs   S2 arr[4];
2028a13326dSisuckatcs };
2038a13326dSisuckatcs 
2048a13326dSisuckatcs void copy_ctor_init_non_pod() {
2058a13326dSisuckatcs   S2::c = 0;
2068a13326dSisuckatcs   S5 orig;
2078a13326dSisuckatcs 
2088a13326dSisuckatcs   S5 copy = orig;
2098a13326dSisuckatcs   clang_analyzer_eval(copy.arr[0].i == 2); // expected-warning{{TRUE}}
2108a13326dSisuckatcs   clang_analyzer_eval(copy.arr[1].i == 3); // expected-warning{{TRUE}}
2118a13326dSisuckatcs   clang_analyzer_eval(copy.arr[2].i == 4); // expected-warning{{TRUE}}
2128a13326dSisuckatcs   clang_analyzer_eval(copy.arr[3].i == 5); // expected-warning{{TRUE}}
2138a13326dSisuckatcs }
2148a13326dSisuckatcs 
2158a13326dSisuckatcs void move_ctor_init_non_pod() {
2168a13326dSisuckatcs   S2::c = 0;
2178a13326dSisuckatcs   S5 orig;
2188a13326dSisuckatcs 
2198a13326dSisuckatcs   S5 moved = (S5 &&) orig;
2208a13326dSisuckatcs 
2218a13326dSisuckatcs   clang_analyzer_eval(moved.arr[0].i == 3); // expected-warning{{TRUE}}
2228a13326dSisuckatcs   clang_analyzer_eval(moved.arr[1].i == 4); // expected-warning{{TRUE}}
2238a13326dSisuckatcs   clang_analyzer_eval(moved.arr[2].i == 5); // expected-warning{{TRUE}}
2248a13326dSisuckatcs   clang_analyzer_eval(moved.arr[3].i == 6); // expected-warning{{TRUE}}
2258a13326dSisuckatcs }
226c81bf940Sisuckatcs 
227c81bf940Sisuckatcs //Note: This is the only solution I could find to check the values without
228c81bf940Sisuckatcs // crashing clang. For more details on the crash see Issue #57135.
229c81bf940Sisuckatcs void lambda_capture_multi_array() {
230c81bf940Sisuckatcs   S3 arr[2][2] = {1,2,3,4};
231c81bf940Sisuckatcs 
232c81bf940Sisuckatcs   {
233c81bf940Sisuckatcs     int x = [arr] { return arr[0][0].i; }();
234c81bf940Sisuckatcs     clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
235c81bf940Sisuckatcs   }
236c81bf940Sisuckatcs 
237c81bf940Sisuckatcs   {
238c81bf940Sisuckatcs     int x = [arr] { return arr[0][1].i; }();
239c81bf940Sisuckatcs     clang_analyzer_eval(x == 2); // expected-warning{{TRUE}}
240c81bf940Sisuckatcs   }
241c81bf940Sisuckatcs 
242c81bf940Sisuckatcs   {
243c81bf940Sisuckatcs     int x = [arr] { return arr[1][0].i; }();
244c81bf940Sisuckatcs     clang_analyzer_eval(x == 3); // expected-warning{{TRUE}}
245c81bf940Sisuckatcs   }
246c81bf940Sisuckatcs 
247c81bf940Sisuckatcs   {
248c81bf940Sisuckatcs     int x = [arr] { return arr[1][1].i; }();
249c81bf940Sisuckatcs     clang_analyzer_eval(x == 4); // expected-warning{{TRUE}}
250c81bf940Sisuckatcs   }
251c81bf940Sisuckatcs }
252c81bf940Sisuckatcs 
253c81bf940Sisuckatcs // This struct will force constructor inlining in MultiWrapper.
254c81bf940Sisuckatcs struct UserDefinedCtor {
255c81bf940Sisuckatcs   int i;
256c81bf940Sisuckatcs   UserDefinedCtor() {}
257c81bf940Sisuckatcs   UserDefinedCtor(const UserDefinedCtor &copy) {
258c81bf940Sisuckatcs     int j = 1;
259c81bf940Sisuckatcs     i = copy.i;
260c81bf940Sisuckatcs   }
261c81bf940Sisuckatcs };
262c81bf940Sisuckatcs 
263c81bf940Sisuckatcs struct MultiWrapper {
264c81bf940Sisuckatcs   UserDefinedCtor arr[2][2];
265c81bf940Sisuckatcs };
266c81bf940Sisuckatcs 
267c81bf940Sisuckatcs void copy_ctor_multi() {
268c81bf940Sisuckatcs   MultiWrapper MW;
269c81bf940Sisuckatcs 
270c81bf940Sisuckatcs   MW.arr[0][0].i = 0;
271c81bf940Sisuckatcs   MW.arr[0][1].i = 1;
272c81bf940Sisuckatcs   MW.arr[1][0].i = 2;
273c81bf940Sisuckatcs   MW.arr[1][1].i = 3;
274c81bf940Sisuckatcs 
275c81bf940Sisuckatcs   MultiWrapper MWCopy = MW;
276c81bf940Sisuckatcs 
277c81bf940Sisuckatcs   clang_analyzer_eval(MWCopy.arr[0][0].i == 0); // expected-warning{{TRUE}}
278c81bf940Sisuckatcs   clang_analyzer_eval(MWCopy.arr[0][1].i == 1); // expected-warning{{TRUE}}
279c81bf940Sisuckatcs   clang_analyzer_eval(MWCopy.arr[1][0].i == 2); // expected-warning{{TRUE}}
280c81bf940Sisuckatcs   clang_analyzer_eval(MWCopy.arr[1][1].i == 3); // expected-warning{{TRUE}}
281c81bf940Sisuckatcs }
282c81bf940Sisuckatcs 
283c81bf940Sisuckatcs void move_ctor_multi() {
284c81bf940Sisuckatcs   MultiWrapper MW;
285c81bf940Sisuckatcs 
286c81bf940Sisuckatcs   MW.arr[0][0].i = 0;
287c81bf940Sisuckatcs   MW.arr[0][1].i = 1;
288c81bf940Sisuckatcs   MW.arr[1][0].i = 2;
289c81bf940Sisuckatcs   MW.arr[1][1].i = 3;
290c81bf940Sisuckatcs 
291c81bf940Sisuckatcs   MultiWrapper MWMove = (MultiWrapper &&) MW;
292c81bf940Sisuckatcs 
293c81bf940Sisuckatcs   clang_analyzer_eval(MWMove.arr[0][0].i == 0); // expected-warning{{TRUE}}
294c81bf940Sisuckatcs   clang_analyzer_eval(MWMove.arr[0][1].i == 1); // expected-warning{{TRUE}}
295c81bf940Sisuckatcs   clang_analyzer_eval(MWMove.arr[1][0].i == 2); // expected-warning{{TRUE}}
296c81bf940Sisuckatcs   clang_analyzer_eval(MWMove.arr[1][1].i == 3); // expected-warning{{TRUE}}
297c81bf940Sisuckatcs }
298c81bf940Sisuckatcs 
299c81bf940Sisuckatcs void structured_binding_multi() {
300c81bf940Sisuckatcs   S3 arr[2][2] = {1,2,3,4};
301c81bf940Sisuckatcs 
302c81bf940Sisuckatcs   auto [a,b] = arr;
303c81bf940Sisuckatcs 
304c81bf940Sisuckatcs   clang_analyzer_eval(a[0].i == 1); // expected-warning{{TRUE}}
305c81bf940Sisuckatcs   clang_analyzer_eval(a[1].i == 2); // expected-warning{{TRUE}}
306c81bf940Sisuckatcs   clang_analyzer_eval(b[0].i == 3); // expected-warning{{TRUE}}
307c81bf940Sisuckatcs   clang_analyzer_eval(b[1].i == 4); // expected-warning{{TRUE}}
308c81bf940Sisuckatcs }
309e3e9082bSisuckatcs 
310e3e9082bSisuckatcs // This snippet used to crash
311e3e9082bSisuckatcs namespace crash {
312e3e9082bSisuckatcs 
313e3e9082bSisuckatcs struct S
314e3e9082bSisuckatcs {
315e3e9082bSisuckatcs   int x;
316e3e9082bSisuckatcs   S() { x = 1; }
317e3e9082bSisuckatcs };
318e3e9082bSisuckatcs 
319e3e9082bSisuckatcs void no_crash() {
320e3e9082bSisuckatcs   S arr[0];
321e3e9082bSisuckatcs   int n = 1;
322e3e9082bSisuckatcs 
323e3e9082bSisuckatcs   auto l = [arr, n] { return n; };
324e3e9082bSisuckatcs 
325e3e9082bSisuckatcs   int x = l();
326e3e9082bSisuckatcs   clang_analyzer_eval(x == 1); // expected-warning{{TRUE}}
327e3e9082bSisuckatcs 
328e3e9082bSisuckatcs   // FIXME: This should be 'Undefined'.
329e3e9082bSisuckatcs   clang_analyzer_eval(arr[0].x); // expected-warning{{UNKNOWN}}
330e3e9082bSisuckatcs }
331e3e9082bSisuckatcs 
332e3e9082bSisuckatcs } // namespace crash
333*a917ae0bSisuckatcs 
334*a917ae0bSisuckatcs namespace array_subscript_initializer {
335*a917ae0bSisuckatcs struct S {
336*a917ae0bSisuckatcs   int x;
337*a917ae0bSisuckatcs };
338*a917ae0bSisuckatcs 
339*a917ae0bSisuckatcs void no_crash() {
340*a917ae0bSisuckatcs   S arr[][2] = {{1, 2}};
341*a917ae0bSisuckatcs 
342*a917ae0bSisuckatcs   const auto [a, b] = arr[0]; // no-crash
343*a917ae0bSisuckatcs 
344*a917ae0bSisuckatcs   clang_analyzer_eval(a.x == 1); // expected-warning{{TRUE}}
345*a917ae0bSisuckatcs   clang_analyzer_eval(b.x == 2); // expected-warning{{TRUE}}
346*a917ae0bSisuckatcs }
347*a917ae0bSisuckatcs } // namespace array_subscript_initializer
348*a917ae0bSisuckatcs 
349*a917ae0bSisuckatcs namespace iterator_initializer {
350*a917ae0bSisuckatcs struct S {
351*a917ae0bSisuckatcs   int x;
352*a917ae0bSisuckatcs };
353*a917ae0bSisuckatcs 
354*a917ae0bSisuckatcs void no_crash() {
355*a917ae0bSisuckatcs   S arr[][2] = {{1, 2}, {3, 4}};
356*a917ae0bSisuckatcs 
357*a917ae0bSisuckatcs   int i = 0;
358*a917ae0bSisuckatcs   for (const auto [a, b] : arr) { // no-crash
359*a917ae0bSisuckatcs     if (i == 0) {
360*a917ae0bSisuckatcs       clang_analyzer_eval(a.x == 1); // expected-warning{{TRUE}}
361*a917ae0bSisuckatcs       clang_analyzer_eval(b.x == 2); // expected-warning{{TRUE}}
362*a917ae0bSisuckatcs     } else {
363*a917ae0bSisuckatcs       clang_analyzer_eval(a.x == 3); // expected-warning{{TRUE}}
364*a917ae0bSisuckatcs       clang_analyzer_eval(b.x == 4); // expected-warning{{TRUE}}
365*a917ae0bSisuckatcs     }
366*a917ae0bSisuckatcs 
367*a917ae0bSisuckatcs     ++i;
368*a917ae0bSisuckatcs   }
369*a917ae0bSisuckatcs }
370*a917ae0bSisuckatcs } // namespace iterator_initializer
371