1 // RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -std=c++11 -verify %s
2 
3 int foo(int x);
4 int bar(int* x);
5 int boo(int& x);
6 int far(const int& x);
7 
8 // Test self-references within initializers which are guaranteed to be
9 // uninitialized.
10 int a = a; // no-warning: used to signal intended lack of initialization.
11 int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
12 int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
13 int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
14 int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
15 
16 // Thes don't warn as they don't require the value.
17 int g = sizeof(g);
18 void* ptr = &ptr;
19 int h = bar(&h);
20 int i = boo(i);
21 int j = far(j);
22 int k = __alignof__(k);
23 
24 int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
25 int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
26 int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
27 
28 void test_stuff () {
29   int a = a; // no-warning: used to signal intended lack of initialization.
30   int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
31   int c = (c + c); // expected-warning {{variable 'c' is uninitialized when used within its own initialization}}
32   int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
33   int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
34   int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
35 
36   // Thes don't warn as they don't require the value.
37   int g = sizeof(g);
38   void* ptr = &ptr;
39   int h = bar(&h);
40   int i = boo(i);
41   int j = far(j);
42   int k = __alignof__(k);
43 
44   int l = k ? l : l;  // expected-warning {{variable 'l' is uninitialized when used within its own initialization}}
45   int m = 1 + (k ? m : m);  // expected-warning {{'m' is uninitialized when used within its own initialization}}
46   int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
47 
48   for (;;) {
49     int a = a; // no-warning: used to signal intended lack of initialization.
50     int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
51     int c = (c + c); // expected-warning {{variable 'c' is uninitialized when used within its own initialization}}
52     int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
53     int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
54     int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
55 
56     // Thes don't warn as they don't require the value.
57     int g = sizeof(g);
58     void* ptr = &ptr;
59     int h = bar(&h);
60     int i = boo(i);
61     int j = far(j);
62     int k = __alignof__(k);
63 
64     int l = k ? l : l;  // expected-warning {{variable 'l' is uninitialized when used within its own initialization}}
65     int m = 1 + (k ? m : m);  // expected-warning {{'m' is uninitialized when used within its own initialization}}
66     int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
67   }
68 }
69 
70 // Test self-references with record types.
71 class A {
72   // Non-POD class.
73   public:
74     enum count { ONE, TWO, THREE };
75     int num;
76     static int count;
77     int get() const { return num; }
78     int get2() { return num; }
79     void set(int x) { num = x; }
80     static int zero() { return 0; }
81 
82     A() {}
83     A(A const &a) {}
84     A(int x) {}
85     A(int *x) {}
86     A(A *a) {}
87     ~A();
88 };
89 
90 A getA() { return A(); }
91 A getA(int x) { return A(); }
92 A getA(A* a) { return A(); }
93 A getA(A a) { return A(); }
94 
95 void setupA(bool x) {
96   A a1;
97   a1.set(a1.get());
98   A a2(a1.get());
99   A a3(a1);
100   A a4(&a4);
101   A a5(a5.zero());
102   A a6(a6.ONE);
103   A a7 = getA();
104   A a8 = getA(a8.TWO);
105   A a9 = getA(&a9);
106   A a10(a10.count);
107 
108   A a11(a11);  // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
109   A a12(a12.get());  // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
110   A a13(a13.num);  // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
111   A a14 = A(a14);  // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
112   A a15 = getA(a15.num);  // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
113   A a16(&a16.num);  // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
114   A a17(a17.get2());  // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
115   A a18 = x ? a18 : a17;  // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
116   A a19 = getA(x ? a19 : a17);  // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
117   A a20{a20};  // expected-warning {{variable 'a20' is uninitialized when used within its own initialization}}
118   A a21 = {a21};  // expected-warning {{variable 'a21' is uninitialized when used within its own initialization}}
119 
120   // FIXME: Make the local uninitialized warning consistant with the global
121   // uninitialized checking.
122   A *a22 = new A(a22->count);  // expected-warning {{variable 'a22' is uninitialized when used within its own initialization}}
123   A *a23 = new A(a23->ONE);  // expected-warning {{variable 'a23' is uninitialized when used within its own initialization}}
124   A *a24 = new A(a24->TWO);  // expected-warning {{variable 'a24' is uninitialized when used within its own initialization}}
125   A *a25 = new A(a25->zero());  // expected-warning {{variable 'a25' is uninitialized when used within its own initialization}}
126 
127   A *a26 = new A(a26->get());    // expected-warning {{variable 'a26' is uninitialized when used within its own initialization}}
128   A *a27 = new A(a27->get2());  // expected-warning {{variable 'a27' is uninitialized when used within its own initialization}}
129   A *a28 = new A(a28->num);  // expected-warning {{variable 'a28' is uninitialized when used within its own initialization}}
130 }
131 
132 bool x;
133 
134 A a1;
135 A a2(a1.get());
136 A a3(a1);
137 A a4(&a4);
138 A a5(a5.zero());
139 A a6(a6.ONE);
140 A a7 = getA();
141 A a8 = getA(a8.TWO);
142 A a9 = getA(&a9);
143 A a10(a10.count);
144 
145 A a11(a11);  // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
146 A a12(a12.get());  // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
147 A a13(a13.num);  // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
148 A a14 = A(a14);  // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
149 A a15 = getA(a15.num);  // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
150 A a16(&a16.num);  // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
151 A a17(a17.get2());  // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
152 A a18 = x ? a18 : a17;  // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
153 A a19 = getA(x ? a19 : a17);  // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
154 A a20{a20};  // expected-warning {{variable 'a20' is uninitialized when used within its own initialization}}
155 A a21 = {a21};  // expected-warning {{variable 'a21' is uninitialized when used within its own initialization}}
156 
157 A *a22 = new A(a22->count);
158 A *a23 = new A(a23->ONE);
159 A *a24 = new A(a24->TWO);
160 A *a25 = new A(a25->zero());
161 
162 A *a26 = new A(a26->get());    // expected-warning {{variable 'a26' is uninitialized when used within its own initialization}}
163 A *a27 = new A(a27->get2());  // expected-warning {{variable 'a27' is uninitialized when used within its own initialization}}
164 A *a28 = new A(a28->num);  // expected-warning {{variable 'a28' is uninitialized when used within its own initialization}}
165 
166 struct B {
167   // POD struct.
168   int x;
169   int *y;
170 };
171 
172 B getB() { return B(); };
173 B getB(int x) { return B(); };
174 B getB(int *x) { return B(); };
175 B getB(B *b) { return B(); };
176 
177 B* getPtrB() { return 0; };
178 B* getPtrB(int x) { return 0; };
179 B* getPtrB(int *x) { return 0; };
180 B* getPtrB(B **b) { return 0; };
181 
182 void setupB() {
183   B b1;
184   B b2(b1);
185   B b3 = { 5, &b3.x };
186   B b4 = getB();
187   B b5 = getB(&b5);
188   B b6 = getB(&b6.x);
189 
190   // Silence unused warning
191   (void) b2;
192   (void) b4;
193 
194   B b7(b7);  // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}}
195   B b8 = getB(b8.x);  // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}}
196   B b9 = getB(b9.y);  // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}}
197   B b10 = getB(-b10.x);  // expected-warning {{variable 'b10' is uninitialized when used within its own initialization}}
198 
199   B* b11 = 0;
200   B* b12(b11);
201   B* b13 = getPtrB();
202   B* b14 = getPtrB(&b14);
203 
204   (void) b12;
205   (void) b13;
206 
207   B* b15 = getPtrB(b15->x);  // expected-warning {{variable 'b15' is uninitialized when used within its own initialization}}
208   B* b16 = getPtrB(b16->y);  // expected-warning {{variable 'b16' is uninitialized when used within its own initialization}}
209 
210   B b17 = { b17.x = 5, b17.y = 0 };
211   B b18 = { b18.x + 1, b18.y };  // expected-warning 2{{variable 'b18' is uninitialized when used within its own initialization}}
212 }
213 
214 B b1;
215 B b2(b1);
216 B b3 = { 5, &b3.x };
217 B b4 = getB();
218 B b5 = getB(&b5);
219 B b6 = getB(&b6.x);
220 
221 B b7(b7);  // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}}
222 B b8 = getB(b8.x);  // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}}
223 B b9 = getB(b9.y);  // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}}
224 B b10 = getB(-b10.x);  // expected-warning {{variable 'b10' is uninitialized when used within its own initialization}}
225 
226 B* b11 = 0;
227 B* b12(b11);
228 B* b13 = getPtrB();
229 B* b14 = getPtrB(&b14);
230 
231 B* b15 = getPtrB(b15->x);  // expected-warning {{variable 'b15' is uninitialized when used within its own initialization}}
232 B* b16 = getPtrB(b16->y);  // expected-warning {{variable 'b16' is uninitialized when used within its own initialization}}
233 
234 B b17 = { b17.x = 5, b17.y = 0 };
235 B b18 = { b18.x + 1, b18.y };  // expected-warning 2{{variable 'b18' is uninitialized when used within its own initialization}}
236 
237 
238 // Also test similar constructs in a field's initializer.
239 struct S {
240   int x;
241   void *ptr;
242 
243   S(bool (*)[1]) : x(x) {} // expected-warning {{field 'x' is uninitialized when used here}}
244   S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field 'x' is uninitialized when used here}}
245   S(bool (*)[3]) : x(x + x) {} // expected-warning 2{{field 'x' is uninitialized when used here}}
246   S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field 'x' is uninitialized when used here}}
247   S(bool (*)[5]) : x(foo(x)) {} // expected-warning {{field 'x' is uninitialized when used here}}
248 
249   // These don't actually require the value of x and so shouldn't warn.
250   S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363
251   S(char (*)[2]) : ptr(&ptr) {}
252   S(char (*)[3]) : x(__alignof__(x)) {}
253   S(char (*)[4]) : x(bar(&x)) {}
254   S(char (*)[5]) : x(boo(x)) {}
255   S(char (*)[6]) : x(far(x)) {}
256 };
257 
258 struct C { char a[100], *e; } car = { .e = car.a };
259 
260 // <rdar://problem/10398199>
261 namespace rdar10398199 {
262   class FooBase { protected: ~FooBase() {} };
263   class Foo : public FooBase {
264   public:
265     operator int&() const;
266   };
267   void stuff();
268   template <typename T> class FooImpl : public Foo {
269     T val;
270   public:
271     FooImpl(const T &x) : val(x) {}
272     ~FooImpl() { stuff(); }
273   };
274 
275   template <typename T> FooImpl<T> makeFoo(const T& x) {
276     return FooImpl<T>(x);
277   }
278 
279   void test() {
280     const Foo &x = makeFoo(42);
281     const int&y = makeFoo(42u);
282     (void)x;
283     (void)y;
284   };
285 }
286 
287 // PR 12325 - this was a false uninitialized value warning due to
288 // a broken CFG.
289 int pr12325(int params) {
290   int x = ({
291     while (false)
292       ;
293     int _v = params;
294     if (false)
295       ;
296     _v; // no-warning
297   });
298   return x;
299 }
300 
301 // Test lambda expressions with -Wuninitialized
302 int test_lambda() {
303   auto f1 = [] (int x, int y) { int z; return x + y + z; }; // expected-warning{{variable 'z' is uninitialized when used here}} expected-note {{initialize the variable 'z' to silence this warning}}
304   return f1(1, 2);
305 }
306 
307 namespace {
308   struct A {
309     enum { A1 };
310     static int A2() {return 5;}
311     int A3;
312     int A4() { return 5;}
313   };
314 
315   struct B {
316     A a;
317   };
318 
319   struct C {
320     C() {}
321     C(int x) {}
322     static A a;
323     B b;
324   };
325   A C::a = A();
326 
327   // Accessing non-static members will give a warning.
328   struct D {
329     C c;
330     D(char (*)[1]) : c(c.b.a.A1) {}
331     D(char (*)[2]) : c(c.b.a.A2()) {}
332     D(char (*)[3]) : c(c.b.a.A3) {}    // expected-warning {{field 'c' is uninitialized when used here}}
333     D(char (*)[4]) : c(c.b.a.A4()) {}  // expected-warning {{field 'c' is uninitialized when used here}}
334 
335     // c::a is static, so it is already initialized
336     D(char (*)[5]) : c(c.a.A1) {}
337     D(char (*)[6]) : c(c.a.A2()) {}
338     D(char (*)[7]) : c(c.a.A3) {}
339     D(char (*)[8]) : c(c.a.A4()) {}
340   };
341 
342   struct E {
343     int b = 1;
344     int c = 1;
345     int a;  // This field needs to be last to prevent the cross field
346             // uninitialized warning.
347     E(char (*)[1]) : a(a ? b : c) {}  // expected-warning {{field 'a' is uninitialized when used here}}
348     E(char (*)[2]) : a(b ? a : a) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
349     E(char (*)[3]) : a(b ? (a) : c) {} // expected-warning {{field 'a' is uninitialized when used here}}
350     E(char (*)[4]) : a(b ? c : (a+c)) {} // expected-warning {{field 'a' is uninitialized when used here}}
351     E(char (*)[5]) : a(b ? c : b) {}
352 
353     E(char (*)[6]) : a(a ?: a) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
354     E(char (*)[7]) : a(b ?: a) {} // expected-warning {{field 'a' is uninitialized when used here}}
355     E(char (*)[8]) : a(a ?: c) {} // expected-warning {{field 'a' is uninitialized when used here}}
356     E(char (*)[9]) : a(b ?: c) {}
357 
358     E(char (*)[10]) : a((a, a, b)) {}
359     E(char (*)[11]) : a((c + a, a + 1, b)) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
360     E(char (*)[12]) : a((b + c, c, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
361     E(char (*)[13]) : a((a, a, a, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
362     E(char (*)[14]) : a((b, c, c)) {}
363   };
364 
365   struct F {
366     int a;
367     F* f;
368     F(int) {}
369     F() {}
370   };
371 
372   int F::*ptr = &F::a;
373   F* F::*f_ptr = &F::f;
374   struct G {
375     F f1, f2;
376     F *f3, *f4;
377     G(char (*)[1]) : f1(f1) {} // expected-warning {{field 'f1' is uninitialized when used here}}
378     G(char (*)[2]) : f2(f1) {}
379     G(char (*)[3]) : f2(F()) {}
380 
381     G(char (*)[4]) : f1(f1.*ptr) {} // expected-warning {{field 'f1' is uninitialized when used here}}
382     G(char (*)[5]) : f2(f1.*ptr) {}
383 
384     G(char (*)[6]) : f3(f3) {}  // expected-warning {{field 'f3' is uninitialized when used here}}
385     G(char (*)[7]) : f3(f3->*f_ptr) {} // expected-warning {{field 'f3' is uninitialized when used here}}
386     G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field 'f3' is uninitialized when used here}}
387   };
388 }
389 
390 namespace statics {
391   static int a = a; // no-warning: used to signal intended lack of initialization.
392   static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
393   static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
394   static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
395   static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
396 
397   // Thes don't warn as they don't require the value.
398   static int g = sizeof(g);
399   int gg = g;  // Silence unneeded warning
400   static void* ptr = &ptr;
401   static int h = bar(&h);
402   static int i = boo(i);
403   static int j = far(j);
404   static int k = __alignof__(k);
405 
406   static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
407   static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
408   static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
409 
410   void test() {
411     static int a = a; // no-warning: used to signal intended lack of initialization.
412     static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
413     static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
414     static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
415     static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
416     static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
417 
418     // Thes don't warn as they don't require the value.
419     static int g = sizeof(g);
420     static void* ptr = &ptr;
421     static int h = bar(&h);
422     static int i = boo(i);
423     static int j = far(j);
424     static int k = __alignof__(k);
425 
426     static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
427     static int m = 1 + (k ? m : m);  // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
428     static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
429    for (;;) {
430       static int a = a; // no-warning: used to signal intended lack of initialization.
431       static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
432       static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
433       static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
434       static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
435       static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
436 
437       // Thes don't warn as they don't require the value.
438       static int g = sizeof(g);
439       static void* ptr = &ptr;
440       static int h = bar(&h);
441       static int i = boo(i);
442       static int j = far(j);
443       static int k = __alignof__(k);
444 
445       static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
446       static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
447       static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
448     }
449   }
450 }
451 
452 namespace in_class_initializers {
453   struct S {
454     S() : a(a + 1) {} // expected-warning{{field 'a' is uninitialized when used here}}
455     int a = 42; // Note: because a is in a member initializer list, this initialization is ignored.
456   };
457 
458   struct T {
459     T() : b(a + 1) {} // No-warning.
460     int a = 42;
461     int b;
462   };
463 
464   struct U {
465     U() : a(b + 1), b(a + 1) {} // expected-warning{{field 'b' is uninitialized when used here}}
466     int a = 42; // Note: because a and b are in the member initializer list, these initializers are ignored.
467     int b = 1;
468   };
469 }
470 
471 namespace references {
472   int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
473   int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
474   int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
475   int &d{d}; // expected-warning{{reference 'd' is not yet bound to a value when used within its own initialization}}
476 
477   struct S {
478     S() : a(a) {} // expected-warning{{reference 'a' is not yet bound to a value when used here}}
479     int &a;
480   };
481 
482   void f() {
483     int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
484     int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
485     int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
486     int &d{d}; // expected-warning{{reference 'd' is not yet bound to a value when used within its own initialization}}
487   }
488 
489   struct T {
490     T() // expected-note{{during field initialization in this constructor}}
491      : a(b), b(a) {} // expected-warning{{reference 'b' is not yet bound to a value when used here}}
492     int &a, &b;
493     int &c = c; // expected-warning{{reference 'c' is not yet bound to a value when used here}}
494   };
495 
496   int x;
497   struct U {
498     U() : b(a) {} // No-warning.
499     int &a = x;
500     int &b;
501   };
502 }
503 
504 namespace operators {
505   struct A {
506     A(bool);
507     bool operator==(A);
508   };
509 
510   A makeA();
511 
512   A a1 = a1 = makeA();  // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
513   A a2 = a2 == a1;  // expected-warning{{variable 'a2' is uninitialized when used within its own initialization}}
514   A a3 = a2 == a3;  // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}}
515 
516   int x = x = 5;
517 }
518 
519 namespace lambdas {
520   struct A {
521     template<typename T> A(T) {}
522     int x;
523   };
524   A a0([] { return a0.x; }); // ok
525   void f() {
526     A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
527     A a2([&] { return a2.x; }); // ok
528   }
529 }
530 
531 namespace record_fields {
532   struct A {
533     A() {}
534     A get();
535     static A num();
536     static A copy(A);
537     static A something(A&);
538   };
539 
540   A ref(A&);
541   A const_ref(const A&);
542   A pointer(A*);
543   A normal(A);
544 
545   struct B {
546     A a;
547     B(char (*)[1]) : a(a) {}  // expected-warning {{uninitialized}}
548     B(char (*)[2]) : a(a.get()) {}  // expected-warning {{uninitialized}}
549     B(char (*)[3]) : a(a.num()) {}
550     B(char (*)[4]) : a(a.copy(a)) {}  // expected-warning {{uninitialized}}
551     B(char (*)[5]) : a(a.something(a)) {}
552     B(char (*)[6]) : a(ref(a)) {}
553     B(char (*)[7]) : a(const_ref(a)) {}
554     B(char (*)[8]) : a(pointer(&a)) {}
555     B(char (*)[9]) : a(normal(a)) {}  // expected-warning {{uninitialized}}
556   };
557   struct C {
558     C() {} // expected-note4{{in this constructor}}
559     A a1 = a1;  // expected-warning {{uninitialized}}
560     A a2 = a2.get();  // expected-warning {{uninitialized}}
561     A a3 = a3.num();
562     A a4 = a4.copy(a4);  // expected-warning {{uninitialized}}
563     A a5 = a5.something(a5);
564     A a6 = ref(a6);
565     A a7 = const_ref(a7);
566     A a8 = pointer(&a8);
567     A a9 = normal(a9);  // expected-warning {{uninitialized}}
568   };
569   struct D {  // expected-note4{{in the implicit default constructor}}
570     A a1 = a1;  // expected-warning {{uninitialized}}
571     A a2 = a2.get();  // expected-warning {{uninitialized}}
572     A a3 = a3.num();
573     A a4 = a4.copy(a4);  // expected-warning {{uninitialized}}
574     A a5 = a5.something(a5);
575     A a6 = ref(a6);
576     A a7 = const_ref(a7);
577     A a8 = pointer(&a8);
578     A a9 = normal(a9);  // expected-warning {{uninitialized}}
579   };
580   D d;
581   struct E {
582     A a1 = a1;
583     A a2 = a2.get();
584     A a3 = a3.num();
585     A a4 = a4.copy(a4);
586     A a5 = a5.something(a5);
587     A a6 = ref(a6);
588     A a7 = const_ref(a7);
589     A a8 = pointer(&a8);
590     A a9 = normal(a9);
591   };
592 }
593 
594 namespace cross_field_warnings {
595   struct A {
596     int a, b;
597     A() {}
598     A(char (*)[1]) : b(a) {}  // expected-warning{{field 'a' is uninitialized when used here}}
599     A(char (*)[2]) : a(b) {}  // expected-warning{{field 'b' is uninitialized when used here}}
600   };
601 
602   struct B {
603     int a = b;  // expected-warning{{field 'b' is uninitialized when used here}}
604     int b;
605     B() {} // expected-note{{during field initialization in this constructor}}
606   };
607 
608   struct C {
609     int a;
610     int b = a;  // expected-warning{{field 'a' is uninitialized when used here}}
611     C(char (*)[1]) : a(5) {}
612     C(char (*)[2]) {} // expected-note{{during field initialization in this constructor}}
613   };
614 
615   struct D {
616     int a;
617     int &b;
618     int &c = a;
619     int d = b;
620     D() : b(a) {}
621   };
622 
623   struct E {
624     int a;
625     int get();
626     static int num();
627     E() {}
628     E(int) {}
629   };
630 
631   struct F {
632     int a;
633     E e;
634     int b;
635     F(char (*)[1]) : a(e.get()) {}  // expected-warning{{field 'e' is uninitialized when used here}}
636     F(char (*)[2]) : a(e.num()) {}
637     F(char (*)[3]) : e(a) {}  // expected-warning{{field 'a' is uninitialized when used here}}
638     F(char (*)[4]) : a(4), e(a) {}
639     F(char (*)[5]) : e(b) {}  // expected-warning{{field 'b' is uninitialized when used here}}
640     F(char (*)[6]) : e(b), b(4) {}  // expected-warning{{field 'b' is uninitialized when used here}}
641   };
642 
643   struct G {
644     G(const A&) {};
645   };
646 
647   struct H {
648     A a1;
649     G g;
650     A a2;
651     H() : g(a1) {}
652     H(int) : g(a2) {}
653   };
654 
655   struct I {
656     I(int*) {}
657   };
658 
659   struct J : public I {
660     int *a;
661     int *b;
662     int c;
663     J() : I((a = new int(5))), b(a), c(*a) {}
664   };
665 
666   struct K {
667     int a = (b = 5);
668     int b = b + 5;
669   };
670 
671   struct L {
672     int a = (b = 5);
673     int b = b + 5;  // expected-warning{{field 'b' is uninitialized when used here}}
674     L() : a(5) {}  // expected-note{{during field initialization in this constructor}}
675   };
676 
677   struct M { };
678 
679   struct N : public M {
680     int a;
681     int b;
682     N() : b(a) { }  // expected-warning{{field 'a' is uninitialized when used here}}
683   };
684 
685   struct O {
686     int x = 42;
687     int get() { return x; }
688   };
689 
690   struct P {
691     O o;
692     int x = o.get();
693     P() : x(o.get()) { }
694   };
695 
696   struct Q {
697     int a;
698     int b;
699     int &c;
700     Q() :
701       a(c = 5),  // expected-warning{{reference 'c' is not yet bound to a value when used here}}
702       b(c),  // expected-warning{{reference 'c' is not yet bound to a value when used here}}
703       c(a) {}
704   };
705 
706   struct R {
707     int a;
708     int b;
709     int c;
710     int d = a + b + c;
711     R() : a(c = 5), b(c), c(a) {}
712   };
713 }
714 
715 namespace base_class {
716   struct A {
717     A (int) {}
718   };
719 
720   struct B : public A {
721     int x;
722     B() : A(x) {}   // expected-warning{{field 'x' is uninitialized when used here}}
723   };
724 
725   struct C : public A {
726     int x;
727     int y;
728     C() : A(y = 4), x(y) {}
729   };
730 }
731