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 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 a, b, c;
    344     E(char (*)[1]) : a(a ? b : c) {}  // expected-warning {{field 'a' is uninitialized when used here}}
    345     E(char (*)[2]) : a(b ? a : a) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
    346     E(char (*)[3]) : a(b ? (a) : c) {} // expected-warning {{field 'a' is uninitialized when used here}}
    347     E(char (*)[4]) : a(b ? c : (a+c)) {} // expected-warning {{field 'a' is uninitialized when used here}}
    348     E(char (*)[5]) : a(b ? c : b) {}
    349 
    350     E(char (*)[6]) : a(a ?: a) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
    351     E(char (*)[7]) : a(b ?: a) {} // expected-warning {{field 'a' is uninitialized when used here}}
    352     E(char (*)[8]) : a(a ?: c) {} // expected-warning {{field 'a' is uninitialized when used here}}
    353     E(char (*)[9]) : a(b ?: c) {}
    354 
    355     E(char (*)[10]) : a((a, a, b)) {}
    356     E(char (*)[11]) : a((c + a, a + 1, b)) {} // expected-warning 2{{field 'a' is uninitialized when used here}}
    357     E(char (*)[12]) : a((b + c, c, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
    358     E(char (*)[13]) : a((a, a, a, a)) {} // expected-warning {{field 'a' is uninitialized when used here}}
    359     E(char (*)[14]) : a((b, c, c)) {}
    360   };
    361 
    362   struct F {
    363     int a;
    364     F* f;
    365     F(int) {}
    366     F() {}
    367   };
    368 
    369   int F::*ptr = &F::a;
    370   F* F::*f_ptr = &F::f;
    371   struct G {
    372     F f1, f2;
    373     F *f3, *f4;
    374     G(char (*)[1]) : f1(f1) {} // expected-warning {{field 'f1' is uninitialized when used here}}
    375     G(char (*)[2]) : f2(f1) {}
    376     G(char (*)[3]) : f2(F()) {}
    377 
    378     G(char (*)[4]) : f1(f1.*ptr) {} // expected-warning {{field 'f1' is uninitialized when used here}}
    379     G(char (*)[5]) : f2(f1.*ptr) {}
    380 
    381     G(char (*)[6]) : f3(f3) {}  // expected-warning {{field 'f3' is uninitialized when used here}}
    382     G(char (*)[7]) : f3(f3->*f_ptr) {} // expected-warning {{field 'f3' is uninitialized when used here}}
    383     G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field 'f3' is uninitialized when used here}}
    384   };
    385 }
    386 
    387 namespace statics {
    388   static int a = a; // no-warning: used to signal intended lack of initialization.
    389   static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
    390   static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
    391   static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
    392   static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
    393 
    394   // Thes don't warn as they don't require the value.
    395   static int g = sizeof(g);
    396   int gg = g;  // Silence unneeded warning
    397   static void* ptr = &ptr;
    398   static int h = bar(&h);
    399   static int i = boo(i);
    400   static int j = far(j);
    401   static int k = __alignof__(k);
    402 
    403   static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
    404   static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
    405   static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
    406 
    407   void test() {
    408     static int a = a; // no-warning: used to signal intended lack of initialization.
    409     static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
    410     static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
    411     static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
    412     static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
    413     static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
    414 
    415     // Thes don't warn as they don't require the value.
    416     static int g = sizeof(g);
    417     static void* ptr = &ptr;
    418     static int h = bar(&h);
    419     static int i = boo(i);
    420     static int j = far(j);
    421     static int k = __alignof__(k);
    422 
    423     static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
    424     static int m = 1 + (k ? m : m);  // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
    425     static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
    426    for (;;) {
    427       static int a = a; // no-warning: used to signal intended lack of initialization.
    428       static int b = b + 1; // expected-warning {{static variable 'b' is suspiciously used within its own initialization}}
    429       static int c = (c + c); // expected-warning 2{{static variable 'c' is suspiciously used within its own initialization}}
    430       static int d = ({ d + d ;}); // expected-warning 2{{static variable 'd' is suspiciously used within its own initialization}}
    431       static int e = static_cast<long>(e) + 1; // expected-warning {{static variable 'e' is suspiciously used within its own initialization}}
    432       static int f = foo(f); // expected-warning {{static variable 'f' is suspiciously used within its own initialization}}
    433 
    434       // Thes don't warn as they don't require the value.
    435       static int g = sizeof(g);
    436       static void* ptr = &ptr;
    437       static int h = bar(&h);
    438       static int i = boo(i);
    439       static int j = far(j);
    440       static int k = __alignof__(k);
    441 
    442       static int l = k ? l : l;  // expected-warning 2{{static variable 'l' is suspiciously used within its own initialization}}
    443       static int m = 1 + (k ? m : m); // expected-warning 2{{static variable 'm' is suspiciously used within its own initialization}}
    444       static int n = -n;  // expected-warning {{static variable 'n' is suspiciously used within its own initialization}}
    445     }
    446   }
    447 }
    448 
    449 namespace in_class_initializers {
    450   struct S {
    451     S() : a(a + 1) {} // expected-warning{{field 'a' is uninitialized when used here}}
    452     int a = 42; // Note: because a is in a member initializer list, this initialization is ignored.
    453   };
    454 
    455   struct T {
    456     T() : b(a + 1) {} // No-warning.
    457     int a = 42;
    458     int b;
    459   };
    460 
    461   struct U {
    462     U() : a(b + 1), b(a + 1) {} // FIXME: Warn here.
    463     int a = 42; // Note: because a and b are in the member initializer list, these initializers are ignored.
    464     int b = 1;
    465   };
    466 }
    467 
    468 namespace references {
    469   int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
    470   int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
    471   int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
    472   int &d{d}; // expected-warning{{reference 'd' is not yet bound to a value when used within its own initialization}}
    473 
    474   struct S {
    475     S() : a(a) {} // expected-warning{{reference 'a' is not yet bound to a value when used here}}
    476     int &a;
    477   };
    478 
    479   void f() {
    480     int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
    481     int &b(b); // expected-warning{{reference 'b' is not yet bound to a value when used within its own initialization}}
    482     int &c = a ? b : c; // expected-warning{{reference 'c' is not yet bound to a value when used within its own initialization}}
    483     int &d{d}; // expected-warning{{reference 'd' is not yet bound to a value when used within its own initialization}}
    484   }
    485 
    486   struct T {
    487     T() : a(b), b(a) {} // FIXME: Warn here.
    488     int &a, &b;
    489     int &c = c; // expected-warning{{reference 'c' is not yet bound to a value when used here}}
    490   };
    491 
    492   int x;
    493   struct U {
    494     U() : b(a) {} // No-warning.
    495     int &a = x;
    496     int &b;
    497   };
    498 }
    499 
    500 namespace operators {
    501   struct A {
    502     A(bool);
    503     bool operator==(A);
    504   };
    505 
    506   A makeA();
    507 
    508   A a1 = a1 = makeA();  // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
    509   A a2 = a2 == a1;  // expected-warning{{variable 'a2' is uninitialized when used within its own initialization}}
    510   A a3 = a2 == a3;  // expected-warning{{variable 'a3' is uninitialized when used within its own initialization}}
    511 
    512   int x = x = 5;
    513 }
    514 
    515 namespace lambdas {
    516   struct A {
    517     template<typename T> A(T) {}
    518     int x;
    519   };
    520   A a0([] { return a0.x; }); // ok
    521   void f() {
    522     A a1([=] { return a1.x; }); // expected-warning{{variable 'a1' is uninitialized when used within its own initialization}}
    523     A a2([&] { return a2.x; }); // ok
    524   }
    525 }
    526