Home | History | Annotate | Download | only in SemaCXX
      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 consistent 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