117 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -verify %s2// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s3// RUN: %clang_cc1 -std=c++11 %s -ast-dump | FileCheck %s --check-prefix=CHECK-AST4 5// definitions for std::move6namespace std {7inline namespace foo {8template <class T> struct remove_reference { typedef T type; };9template <class T> struct remove_reference<T&> { typedef T type; };10template <class T> struct remove_reference<T&&> { typedef T type; };11 12template <class T> typename remove_reference<T>::type &&move(T &&t);13}14}15 16// test1 and test2 should not warn until after implementation of DR1579.17struct A {};18struct B : public A {};19 20A test1(B b1) {21 B b2;22 return b1;23 return b2;24 return std::move(b1);25 return std::move(b2);26}27 28struct C {29 C() {}30 C(A) {}31};32 33C test2(A a1, B b1) {34 A a2;35 B b2;36 37 return a1;38 return a2;39 return b1;40 return b2;41 42 return std::move(a1);43 return std::move(a2);44 return std::move(b1);45 return std::move(b2);46}47 48// Copy of tests above with types changed to reference types.49A test3(B& b1) {50 B& b2 = b1;51 return b1;52 return b2;53 return std::move(b1);54 return std::move(b2);55}56 57C test4(A& a1, B& b1) {58 A& a2 = a1;59 B& b2 = b1;60 61 return a1;62 return a2;63 return b1;64 return b2;65 66 return std::move(a1);67 return std::move(a2);68 return std::move(b1);69 return std::move(b2);70}71 72// PR23819, case 273struct D {};74D test5(D d) {75 return d;76 // Verify the implicit move from the AST dump77 // CHECK-AST: ReturnStmt{{.*}}line:[[@LINE-2]]78 // CHECK-AST-NEXT: CXXConstructExpr{{.*}}D{{.*}}void (D &&)79 // CHECK-AST-NEXT: ImplicitCastExpr80 // CHECK-AST-NEXT: DeclRefExpr{{.*}}ParmVar{{.*}}'d'81 82 return std::move(d);83 // expected-warning@-1{{redundant move in return statement}}84 // expected-note@-2{{remove std::move call here}}85 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""86 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:""87}88 89namespace templates {90 struct A {};91 struct B { B(A); };92 93 // Warn once here since the type is not dependent.94 template <typename T>95 A test1(A a) {96 return std::move(a);97 // expected-warning@-1{{redundant move in return statement}}98 // expected-note@-2{{remove std::move call here}}99 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:""100 // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""101 }102 void run_test1() {103 test1<A>(A());104 test1<B>(A());105 }106 107 // T1 and T2 may not be the same, the warning may not always apply.108 template <typename T1, typename T2>109 T1 test2(T2 t) {110 return std::move(t);111 }112 void run_test2() {113 test2<A, A>(A());114 test2<B, A>(A());115 }116}117