1// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -std=c++11 -verify %s
2
3int foo(int x);
4int bar(int* x);
5int boo(int& x);
6int far(const int& x);
7
8// Test self-references within initializers which are guaranteed to be
9// uninitialized.
10int a = a; // no-warning: used to signal intended lack of initialization.
11int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
12int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
13int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
14int 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.
17int g = sizeof(g);
18void* ptr = &ptr;
19int h = bar(&h);
20int i = boo(i);
21int j = far(j);
22int k = __alignof__(k);
23
24int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
25int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
26int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
27
28void 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;  // FIXME: warn here
45  int m = 1 + (k ? m : m);  // FIXME: warn here
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;  // FIXME: warn here
65    int m = 1 + (k ? m : m);  // FIXME: warn here
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.
71class 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
90A getA() { return A(); }
91A getA(int x) { return A(); }
92A getA(A* a) { return A(); }
93A getA(A a) { return A(); }
94
95void 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}
118
119bool x;
120
121A a1;
122A a2(a1.get());
123A a3(a1);
124A a4(&a4);
125A a5(a5.zero());
126A a6(a6.ONE);
127A a7 = getA();
128A a8 = getA(a8.TWO);
129A a9 = getA(&a9);
130A a10(a10.count);
131
132A a11(a11);  // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
133A a12(a12.get());  // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
134A a13(a13.num);  // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
135A a14 = A(a14);  // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
136A a15 = getA(a15.num);  // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
137A a16(&a16.num);  // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
138A a17(a17.get2());  // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
139A a18 = x ? a18 : a17;  // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
140A a19 = getA(x ? a19 : a17);  // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
141
142struct B {
143  // POD struct.
144  int x;
145  int *y;
146};
147
148B getB() { return B(); };
149B getB(int x) { return B(); };
150B getB(int *x) { return B(); };
151B getB(B *b) { return B(); };
152
153void setupB() {
154  B b1;
155  B b2(b1);
156  B b3 = { 5, &b3.x };
157  B b4 = getB();
158  B b5 = getB(&b5);
159  B b6 = getB(&b6.x);
160
161  // Silence unused warning
162  (void) b2;
163  (void) b4;
164
165  B b7(b7);  // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}}
166  B b8 = getB(b8.x);  // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}}
167  B b9 = getB(b9.y);  // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}}
168  B b10 = getB(-b10.x);  // expected-warning {{variable 'b10' is uninitialized when used within its own initialization}}
169}
170
171// Also test similar constructs in a field's initializer.
172struct S {
173  int x;
174  void *ptr;
175
176  S(bool (*)[1]) : x(x) {} // expected-warning {{field is uninitialized when used here}}
177  S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field is uninitialized when used here}}
178  S(bool (*)[3]) : x(x + x) {} // expected-warning 2{{field is uninitialized when used here}}
179  S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field is uninitialized when used here}}
180  S(bool (*)[5]) : x(foo(x)) {} // expected-warning {{field is uninitialized when used here}}
181
182  // These don't actually require the value of x and so shouldn't warn.
183  S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363
184  S(char (*)[2]) : ptr(&ptr) {}
185  S(char (*)[3]) : x(__alignof__(x)) {}
186  S(char (*)[4]) : x(bar(&x)) {}
187  S(char (*)[5]) : x(boo(x)) {}
188  S(char (*)[6]) : x(far(x)) {}
189};
190
191struct C { char a[100], *e; } car = { .e = car.a };
192
193// <rdar://problem/10398199>
194namespace rdar10398199 {
195  class FooBase { protected: ~FooBase() {} };
196  class Foo : public FooBase {
197  public:
198    operator int&() const;
199  };
200  void stuff();
201  template <typename T> class FooImpl : public Foo {
202    T val;
203  public:
204    FooImpl(const T &x) : val(x) {}
205    ~FooImpl() { stuff(); }
206  };
207
208  template <typename T> FooImpl<T> makeFoo(const T& x) {
209    return FooImpl<T>(x);
210  }
211
212  void test() {
213    const Foo &x = makeFoo(42);
214    const int&y = makeFoo(42u);
215    (void)x;
216    (void)y;
217  };
218}
219
220// PR 12325 - this was a false uninitialized value warning due to
221// a broken CFG.
222int pr12325(int params) {
223  int x = ({
224    while (false)
225      ;
226    int _v = params;
227    if (false)
228      ;
229    _v; // no-warning
230  });
231  return x;
232}
233
234// Test lambda expressions with -Wuninitialized
235int test_lambda() {
236  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}}
237  return f1(1, 2);
238}
239
240namespace {
241  struct A {
242    enum { A1 };
243    static int A2() {return 5;}
244    int A3;
245    int A4() { return 5;}
246  };
247
248  struct B {
249    A a;
250  };
251
252  struct C {
253    C() {}
254    C(int x) {}
255    static A a;
256    B b;
257  };
258  A C::a = A();
259
260  // Accessing non-static members will give a warning.
261  struct D {
262    C c;
263    D(char (*)[1]) : c(c.b.a.A1) {}
264    D(char (*)[2]) : c(c.b.a.A2()) {}
265    D(char (*)[3]) : c(c.b.a.A3) {}    // expected-warning {{field is uninitialized when used here}}
266    D(char (*)[4]) : c(c.b.a.A4()) {}  // expected-warning {{field is uninitialized when used here}}
267
268    // c::a is static, so it is already initialized
269    D(char (*)[5]) : c(c.a.A1) {}
270    D(char (*)[6]) : c(c.a.A2()) {}
271    D(char (*)[7]) : c(c.a.A3) {}
272    D(char (*)[8]) : c(c.a.A4()) {}
273  };
274
275  struct E {
276    int a, b, c;
277    E(char (*)[1]) : a(a ? b : c) {}  // expected-warning {{field is uninitialized when used here}}
278    E(char (*)[2]) : a(b ? a : a) {} // expected-warning 2{{field is uninitialized when used here}}
279    E(char (*)[3]) : a(b ? (a) : c) {} // expected-warning {{field is uninitialized when used here}}
280    E(char (*)[4]) : a(b ? c : (a+c)) {} // expected-warning {{field is uninitialized when used here}}
281    E(char (*)[5]) : a(b ? c : b) {}
282
283    E(char (*)[6]) : a(a ?: a) {} // expected-warning 2{{field is uninitialized when used here}}
284    E(char (*)[7]) : a(b ?: a) {} // expected-warning {{field is uninitialized when used here}}
285    E(char (*)[8]) : a(a ?: c) {} // expected-warning {{field is uninitialized when used here}}
286    E(char (*)[9]) : a(b ?: c) {}
287
288    E(char (*)[10]) : a((a, a, b)) {}
289    E(char (*)[11]) : a((c + a, a + 1, b)) {} // expected-warning 2{{field is uninitialized when used here}}
290    E(char (*)[12]) : a((b + c, c, a)) {} // expected-warning {{field is uninitialized when used here}}
291    E(char (*)[13]) : a((a, a, a, a)) {} // expected-warning {{field is uninitialized when used here}}
292    E(char (*)[14]) : a((b, c, c)) {}
293  };
294
295  struct F {
296    int a;
297    F* f;
298    F(int) {}
299    F() {}
300  };
301
302  int F::*ptr = &F::a;
303  F* F::*f_ptr = &F::f;
304  struct G {
305    F f1, f2;
306    F *f3, *f4;
307    G(char (*)[1]) : f1(f1) {} // expected-warning {{field is uninitialized when used here}}
308    G(char (*)[2]) : f2(f1) {}
309    G(char (*)[3]) : f2(F()) {}
310
311    G(char (*)[4]) : f1(f1.*ptr) {} // expected-warning {{field is uninitialized when used here}}
312    G(char (*)[5]) : f2(f1.*ptr) {}
313
314    G(char (*)[6]) : f3(f3) {}  // expected-warning {{field is uninitialized when used here}}
315    G(char (*)[7]) : f3(f3->*f_ptr) {} // expected-warning {{field is uninitialized when used here}}
316    G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}}
317  };
318}
319
320namespace statics {
321  static int a = a; // no-warning: used to signal intended lack of initialization.
322  static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
323  static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
324  static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
325  static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
326
327  // Thes don't warn as they don't require the value.
328  static int g = sizeof(g);
329  int gg = g;  // Silence unneeded warning
330  static void* ptr = &ptr;
331  static int h = bar(&h);
332  static int i = boo(i);
333  static int j = far(j);
334  static int k = __alignof__(k);
335
336  static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
337  static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
338  static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
339
340  void test() {
341    static int a = a; // no-warning: used to signal intended lack of initialization.
342    static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
343    static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
344    static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
345    static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
346    static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
347
348    // Thes don't warn as they don't require the value.
349    static int g = sizeof(g);
350    static void* ptr = &ptr;
351    static int h = bar(&h);
352    static int i = boo(i);
353    static int j = far(j);
354    static int k = __alignof__(k);
355
356    static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
357    static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
358    static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
359   for (;;) {
360      static int a = a; // no-warning: used to signal intended lack of initialization.
361      static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
362      static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
363      static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
364      static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
365      static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
366
367      // Thes don't warn as they don't require the value.
368      static int g = sizeof(g);
369      static void* ptr = &ptr;
370      static int h = bar(&h);
371      static int i = boo(i);
372      static int j = far(j);
373      static int k = __alignof__(k);
374
375      static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
376      static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
377      static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
378    }
379  }
380}
381
382namespace references {
383  int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
384
385  struct S {
386    S() : a(a) {} // expected-warning{{reference is not yet bound to a value when used here}}
387    int &a;
388  };
389
390  void f() {
391    int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
392  }
393
394  struct T {
395    T() : a(b), b(a) {} // FIXME: Warn here.
396    int &a, &b;
397    int &c = c; // FIXME: Warn here.
398  };
399}
400