1// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -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}} 13void test() { 14 int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}} 15} 16int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}} 17int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}} 18 19// Thes don't warn as they don't require the value. 20int g = sizeof(g); 21void* ptr = &ptr; 22int h = bar(&h); 23int i = boo(i); 24int j = far(j); 25int k = __alignof__(k); 26 27 28// Test self-references with record types. 29class A { 30 // Non-POD class. 31 public: 32 enum count { ONE, TWO, THREE }; 33 int num; 34 static int count; 35 int get() const { return num; } 36 void set(int x) { num = x; } 37 static int zero() { return 0; } 38 39 A() {} 40 A(A const &a) {} 41 A(int x) {} 42 A(int *x) {} 43 A(A *a) {} 44}; 45 46A getA() { return A(); } 47A getA(int x) { return A(); } 48A getA(A* a) { return A(); } 49 50void setupA() { 51 A a1; 52 a1.set(a1.get()); 53 A a2(a1.get()); 54 A a3(a1); 55 A a4(&a4); 56 A a5(a5.zero()); 57 A a6(a6.ONE); 58 A a7 = getA(); 59 A a8 = getA(a8.TWO); 60 A a9 = getA(&a9); 61 A a10(a10.count); 62 63 A a11(a11); // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}} 64 A a12(a12.get()); // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}} 65 A a13(a13.num); // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}} 66 A a14 = A(a14); // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}} 67 A a15 = getA(a15.num); // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}} 68 A a16(&a16.num); // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}} 69} 70 71struct B { 72 // POD struct. 73 int x; 74 int *y; 75}; 76 77B getB() { return B(); }; 78B getB(int x) { return B(); }; 79B getB(int *x) { return B(); }; 80B getB(B *b) { return B(); }; 81 82void setupB() { 83 B b1; 84 B b2(b1); 85 B b3 = { 5, &b3.x }; 86 B b4 = getB(); 87 B b5 = getB(&b5); 88 B b6 = getB(&b6.x); 89 90 // Silence unused warning 91 (void) b2; 92 (void) b4; 93 94 B b7(b7); // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}} 95 B b8 = getB(b8.x); // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}} 96 B b9 = getB(b9.y); // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}} 97} 98 99// Also test similar constructs in a field's initializer. 100struct S { 101 int x; 102 void *ptr; 103 104 S(bool (*)[1]) : x(x) {} // expected-warning {{field is uninitialized when used here}} 105 S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field is uninitialized when used here}} 106 S(bool (*)[3]) : x(x + x) {} // expected-warning {{field is uninitialized when used here}} 107 S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field is uninitialized when used here}} 108 S(bool (*)[5]) : x(foo(x)) {} // FIXME: This should warn! 109 110 // These don't actually require the value of x and so shouldn't warn. 111 S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363 112 S(char (*)[2]) : ptr(&ptr) {} 113 S(char (*)[3]) : x(__alignof__(x)) {} 114 S(char (*)[4]) : x(bar(&x)) {} 115 S(char (*)[5]) : x(boo(x)) {} 116 S(char (*)[6]) : x(far(x)) {} 117}; 118 119struct C { char a[100], *e; } car = { .e = car.a }; 120