// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -std=c++11 -verify %s
+// definitions for std::move
+namespace std {
+inline namespace foo {
+template <class T> struct remove_reference { typedef T type; };
+template <class T> struct remove_reference<T&> { typedef T type; };
+template <class T> struct remove_reference<T&&> { typedef T type; };
+
+template <class T> typename remove_reference<T>::type&& move(T&& t);
+}
+}
+
int foo(int x);
int bar(int* x);
int boo(int& x);
int far(const int& x);
+int moved(int&& x);
// Test self-references within initializers which are guaranteed to be
// uninitialized.
int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+int o = std::move(o); // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+const int p = std::move(p); // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
+int q = moved(std::move(q)); // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
void test_stuff () {
int a = a; // no-warning: used to signal intended lack of initialization.
int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}}
int m = 1 + (k ? m : m); // expected-warning {{'m' is uninitialized when used within its own initialization}}
int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+ int o = std::move(o); // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+ const int p = std::move(p); // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
+ int q = moved(std::move(q)); // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
for (;;) {
int a = a; // no-warning: used to signal intended lack of initialization.
int l = k ? l : l; // expected-warning {{variable 'l' is uninitialized when used within its own initialization}}
int m = 1 + (k ? m : m); // expected-warning {{'m' is uninitialized when used within its own initialization}}
int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+ int o = std::move(o); // expected-warning {{variable 'o' is uninitialized when used within its own initialization}}
+ const int p = std::move(p); // expected-warning {{variable 'p' is uninitialized when used within its own initialization}}
+ int q = moved(std::move(q)); // expected-warning {{variable 'q' is uninitialized when used within its own initialization}}
}
}
A(int x) {}
A(int *x) {}
A(A *a) {}
+ A(A &&a) {}
~A();
};
A getA(int x) { return A(); }
A getA(A* a) { return A(); }
A getA(A a) { return A(); }
+A moveA(A&& a) { return A(); }
void setupA(bool x) {
A a1;
const A a29(a29); // expected-warning {{variable 'a29' is uninitialized when used within its own initialization}}
const A a30 = a30; // expected-warning {{variable 'a30' is uninitialized when used within its own initialization}}
+
+ A a31 = std::move(a31); // expected-warning {{variable 'a31' is uninitialized when used within its own initialization}}
+ A a32 = moveA(std::move(a32)); // expected-warning {{variable 'a32' is uninitialized when used within its own initialization}}
+ A a33 = A(std::move(a33)); // expected-warning {{variable 'a33' is uninitialized when used within its own initialization}}
+ A a34(std::move(a34)); // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}}
}
bool x;
const A a29(a29); // expected-warning {{variable 'a29' is uninitialized when used within its own initialization}}
const A a30 = a30; // expected-warning {{variable 'a30' is uninitialized when used within its own initialization}}
+A a31 = std::move(a31); // expected-warning {{variable 'a31' is uninitialized when used within its own initialization}}
+A a32 = moveA(std::move(a32)); // expected-warning {{variable 'a32' is uninitialized when used within its own initialization}}
+A a33 = A(std::move(a33)); // expected-warning {{variable 'a33' is uninitialized when used within its own initialization}}
+A a34(std::move(a34)); // expected-warning {{variable 'a34' is uninitialized when used within its own initialization}}
struct B {
// POD struct.
int x;
B getB(int x) { return B(); };
B getB(int *x) { return B(); };
B getB(B *b) { return B(); };
+B moveB(B &&b) { return B(); };
B* getPtrB() { return 0; };
B* getPtrB(int x) { return 0; };
const B b19 = b19; // expected-warning {{variable 'b19' is uninitialized when used within its own initialization}}
const B b20(b20); // expected-warning {{variable 'b20' is uninitialized when used within its own initialization}}
+ B b21 = std::move(b21); // expected-warning {{variable 'b21' is uninitialized when used within its own initialization}}
+ B b22 = moveB(std::move(b22)); // expected-warning {{variable 'b22' is uninitialized when used within its own initialization}}
+ B b23 = B(std::move(b23)); // expected-warning {{variable 'b23' is uninitialized when used within its own initialization}}
}
B b1;
const B b19 = b19; // expected-warning {{variable 'b19' is uninitialized when used within its own initialization}}
const B b20(b20); // expected-warning {{variable 'b20' is uninitialized when used within its own initialization}}
+B b21 = std::move(b21); // expected-warning {{variable 'b21' is uninitialized when used within its own initialization}}
+B b22 = moveB(std::move(b22)); // expected-warning {{variable 'b22' is uninitialized when used within its own initialization}}
+B b23 = B(std::move(b23)); // expected-warning {{variable 'b23' is uninitialized when used within its own initialization}}
+
// Also test similar constructs in a field's initializer.
struct S {
int x;
A const_ref(const A&);
A pointer(A*);
A normal(A);
+ A rref(A&&);
struct B {
A a;
B(char (*)[7]) : a(const_ref(a)) {}
B(char (*)[8]) : a(pointer(&a)) {}
B(char (*)[9]) : a(normal(a)) {} // expected-warning {{uninitialized}}
+ B(char (*)[10]) : a(std::move(a)) {} // expected-warning {{uninitialized}}
+ B(char (*)[11]) : a(A(std::move(a))) {} // expected-warning {{uninitialized}}
+ B(char (*)[12]) : a(rref(std::move(a))) {} // expected-warning {{uninitialized}}
};
struct C {
- C() {} // expected-note5{{in this constructor}}
+ C() {} // expected-note8{{in this constructor}}
A a1 = a1; // expected-warning {{uninitialized}}
A a2 = a2.get(); // expected-warning {{uninitialized}}
A a3 = a3.num();
A a8 = pointer(&a8);
A a9 = normal(a9); // expected-warning {{uninitialized}}
const A a10 = a10; // expected-warning {{uninitialized}}
+ A a11 = std::move(a11); // expected-warning {{uninitialized}}
+ A a12 = A(std::move(a12)); // expected-warning {{uninitialized}}
+ A a13 = rref(std::move(a13)); // expected-warning {{uninitialized}}
};
- struct D { // expected-note5{{in the implicit default constructor}}
+ struct D { // expected-note8{{in the implicit default constructor}}
A a1 = a1; // expected-warning {{uninitialized}}
A a2 = a2.get(); // expected-warning {{uninitialized}}
A a3 = a3.num();
A a8 = pointer(&a8);
A a9 = normal(a9); // expected-warning {{uninitialized}}
const A a10 = a10; // expected-warning {{uninitialized}}
+ A a11 = std::move(a11); // expected-warning {{uninitialized}}
+ A a12 = A(std::move(a12)); // expected-warning {{uninitialized}}
+ A a13 = rref(std::move(a13)); // expected-warning {{uninitialized}}
};
D d;
struct E {
A a8 = pointer(&a8);
A a9 = normal(a9);
const A a10 = a10;
+ A a11 = std::move(a11);
+ A a12 = A(std::move(a12));
+ A a13 = rref(std::move(a13));
};
}