uninitialized.cpp revision 1a5d35539a16f3b2eb2426f3f23a8376b190741c
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 ~A(); 45}; 46 47A getA() { return A(); } 48A getA(int x) { return A(); } 49A getA(A* a) { return A(); } 50 51void setupA() { 52 A a1; 53 a1.set(a1.get()); 54 A a2(a1.get()); 55 A a3(a1); 56 A a4(&a4); 57 A a5(a5.zero()); 58 A a6(a6.ONE); 59 A a7 = getA(); 60 A a8 = getA(a8.TWO); 61 A a9 = getA(&a9); 62 A a10(a10.count); 63 64 A a11(a11); // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}} 65 A a12(a12.get()); // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}} 66 A a13(a13.num); // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}} 67 A a14 = A(a14); // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}} 68 A a15 = getA(a15.num); // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}} 69 A a16(&a16.num); // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}} 70} 71 72struct B { 73 // POD struct. 74 int x; 75 int *y; 76}; 77 78B getB() { return B(); }; 79B getB(int x) { return B(); }; 80B getB(int *x) { return B(); }; 81B getB(B *b) { return B(); }; 82 83void setupB() { 84 B b1; 85 B b2(b1); 86 B b3 = { 5, &b3.x }; 87 B b4 = getB(); 88 B b5 = getB(&b5); 89 B b6 = getB(&b6.x); 90 91 // Silence unused warning 92 (void) b2; 93 (void) b4; 94 95 B b7(b7); // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}} 96 B b8 = getB(b8.x); // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}} 97 B b9 = getB(b9.y); // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}} 98} 99 100// Also test similar constructs in a field's initializer. 101struct S { 102 int x; 103 void *ptr; 104 105 S(bool (*)[1]) : x(x) {} // expected-warning {{field is uninitialized when used here}} 106 S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field is uninitialized when used here}} 107 S(bool (*)[3]) : x(x + x) {} // expected-warning {{field is uninitialized when used here}} 108 S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field is uninitialized when used here}} 109 S(bool (*)[5]) : x(foo(x)) {} // FIXME: This should warn! 110 111 // These don't actually require the value of x and so shouldn't warn. 112 S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363 113 S(char (*)[2]) : ptr(&ptr) {} 114 S(char (*)[3]) : x(__alignof__(x)) {} 115 S(char (*)[4]) : x(bar(&x)) {} 116 S(char (*)[5]) : x(boo(x)) {} 117 S(char (*)[6]) : x(far(x)) {} 118}; 119 120struct C { char a[100], *e; } car = { .e = car.a }; 121 122// <rdar://problem/10398199> 123namespace rdar10398199 { 124 class FooBase { protected: ~FooBase() {} }; 125 class Foo : public FooBase { 126 public: 127 operator int&() const; 128 }; 129 void stuff(); 130 template <typename T> class FooImpl : public Foo { 131 T val; 132 public: 133 FooImpl(const T &x) : val(x) {} 134 ~FooImpl() { stuff(); } 135 }; 136 137 template <typename T> FooImpl<T> makeFoo(const T& x) { 138 return FooImpl<T>(x); 139 } 140 141 void test() { 142 const Foo &x = makeFoo(42); 143 const int&y = makeFoo(42u); 144 (void)x; 145 (void)y; 146 }; 147} 148