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