summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/warn-pessmizing-move.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/warn-pessmizing-move.cpp')
-rw-r--r--test/SemaCXX/warn-pessmizing-move.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/test/SemaCXX/warn-pessmizing-move.cpp b/test/SemaCXX/warn-pessmizing-move.cpp
new file mode 100644
index 0000000..6b49944
--- /dev/null
+++ b/test/SemaCXX/warn-pessmizing-move.cpp
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %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);
+}
+}
+
+struct A {};
+struct B {
+ B() {}
+ B(A) {}
+};
+
+A test1(A a1) {
+ A a2;
+ return a1;
+ return a2;
+ return std::move(a1);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+ return std::move(a2);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+}
+
+B test2(A a1, B b1) {
+ // Object is different than return type so don't warn.
+ A a2;
+ return a1;
+ return a2;
+ return std::move(a1);
+ return std::move(a2);
+
+ B b2;
+ return b1;
+ return b2;
+ return std::move(b1);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+ return std::move(b2);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+}
+
+A global_a;
+A test3() {
+ // Don't warn when object is not local.
+ return global_a;
+ return std::move(global_a);
+ static A static_a;
+ return static_a;
+ return std::move(static_a);
+
+}
+
+A test4() {
+ return A();
+ return test3();
+
+ return std::move(A());
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""
+ return std::move(test3());
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:""
+}
+
+void test5(A) {
+ test5(A());
+ test5(test4());
+
+ test5(std::move(A()));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+ test5(std::move(test4()));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:""
+}
+
+void test6() {
+ A a1 = A();
+ A a2 = test3();
+
+ A a3 = std::move(A());
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""
+ A a4 = std::move(test3());
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:""
+}
+
+A test7() {
+ A a1 = std::move(A());
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""
+ A a2 = std::move((A()));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:""
+ A a3 = (std::move(A()));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:""
+ A a4 = (std::move((A())));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:""
+
+ return std::move(a1);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:""
+ return std::move((a1));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:""
+ return (std::move(a1));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""
+ return (std::move((a1)));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:""
+}
+
+#define wrap1(x) x
+#define wrap2(x) x
+
+// Macro test. Since the std::move call is outside the macro, it is
+// safe to suggest a fix-it.
+A test8(A a) {
+ return std::move(a);
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:""
+ return std::move(wrap1(a));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:28-[[@LINE-4]]:29}:""
+ return std::move(wrap1(wrap2(a)));
+ // expected-warning@-1{{prevents copy elision}}
+ // expected-note@-2{{remove std::move call}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:35-[[@LINE-4]]:36}:""
+}
+
+#define test9 \
+ A test9(A a) { \
+ return std::move(a); \
+ }
+
+// Macro test. The std::call is inside the macro, so no fix-it is suggested.
+test9
+// expected-warning@-1{{prevents copy elision}}
+// CHECK-NOT: fix-it
+
+#define return_a return std::move(a)
+
+// Macro test. The std::call is inside the macro, so no fix-it is suggested.
+A test10(A a) {
+ return_a;
+ // expected-warning@-1{{prevents copy elision}}
+ // CHECK-NOT: fix-it
+}
OpenPOWER on IntegriCloud