1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -verify %s 2*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -Wpessimizing-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s 3*67e74705SXin Li 4*67e74705SXin Li // definitions for std::move 5*67e74705SXin Li namespace std { 6*67e74705SXin Li inline namespace foo { 7*67e74705SXin Li template <class T> struct remove_reference { typedef T type; }; 8*67e74705SXin Li template <class T> struct remove_reference<T&> { typedef T type; }; 9*67e74705SXin Li template <class T> struct remove_reference<T&&> { typedef T type; }; 10*67e74705SXin Li 11*67e74705SXin Li template <class T> typename remove_reference<T>::type &&move(T &&t); 12*67e74705SXin Li } 13*67e74705SXin Li } 14*67e74705SXin Li 15*67e74705SXin Li struct A {}; 16*67e74705SXin Li struct B { BB17*67e74705SXin Li B() {} BB18*67e74705SXin Li B(A) {} 19*67e74705SXin Li }; 20*67e74705SXin Li test1(A a1)21*67e74705SXin LiA test1(A a1) { 22*67e74705SXin Li A a2; 23*67e74705SXin Li return a1; 24*67e74705SXin Li return a2; 25*67e74705SXin Li return std::move(a1); 26*67e74705SXin Li return std::move(a2); 27*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 28*67e74705SXin Li // expected-note@-2{{remove std::move call}} 29*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 30*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" 31*67e74705SXin Li } 32*67e74705SXin Li test2(A a1,B b1)33*67e74705SXin LiB test2(A a1, B b1) { 34*67e74705SXin Li // Object is different than return type so don't warn. 35*67e74705SXin Li A a2; 36*67e74705SXin Li return a1; 37*67e74705SXin Li return a2; 38*67e74705SXin Li return std::move(a1); 39*67e74705SXin Li return std::move(a2); 40*67e74705SXin Li 41*67e74705SXin Li B b2; 42*67e74705SXin Li return b1; 43*67e74705SXin Li return b2; 44*67e74705SXin Li return std::move(b1); 45*67e74705SXin Li return std::move(b2); 46*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 47*67e74705SXin Li // expected-note@-2{{remove std::move call}} 48*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 49*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" 50*67e74705SXin Li } 51*67e74705SXin Li 52*67e74705SXin Li A global_a; test3()53*67e74705SXin LiA test3() { 54*67e74705SXin Li // Don't warn when object is not local. 55*67e74705SXin Li return global_a; 56*67e74705SXin Li return std::move(global_a); 57*67e74705SXin Li static A static_a; 58*67e74705SXin Li return static_a; 59*67e74705SXin Li return std::move(static_a); 60*67e74705SXin Li 61*67e74705SXin Li } 62*67e74705SXin Li test4()63*67e74705SXin LiA test4() { 64*67e74705SXin Li return A(); 65*67e74705SXin Li return test3(); 66*67e74705SXin Li 67*67e74705SXin Li return std::move(A()); 68*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 69*67e74705SXin Li // expected-note@-2{{remove std::move call}} 70*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 71*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" 72*67e74705SXin Li return std::move(test3()); 73*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 74*67e74705SXin Li // expected-note@-2{{remove std::move call}} 75*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 76*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:"" 77*67e74705SXin Li } 78*67e74705SXin Li test5(A)79*67e74705SXin Livoid test5(A) { 80*67e74705SXin Li test5(A()); 81*67e74705SXin Li test5(test4()); 82*67e74705SXin Li 83*67e74705SXin Li test5(std::move(A())); 84*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 85*67e74705SXin Li // expected-note@-2{{remove std::move call}} 86*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:"" 87*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" 88*67e74705SXin Li test5(std::move(test4())); 89*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 90*67e74705SXin Li // expected-note@-2{{remove std::move call}} 91*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:19}:"" 92*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:"" 93*67e74705SXin Li } 94*67e74705SXin Li test6()95*67e74705SXin Livoid test6() { 96*67e74705SXin Li A a1 = A(); 97*67e74705SXin Li A a2 = test3(); 98*67e74705SXin Li 99*67e74705SXin Li A a3 = std::move(A()); 100*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 101*67e74705SXin Li // expected-note@-2{{remove std::move call}} 102*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 103*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" 104*67e74705SXin Li A a4 = std::move(test3()); 105*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 106*67e74705SXin Li // expected-note@-2{{remove std::move call}} 107*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 108*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:27-[[@LINE-4]]:28}:"" 109*67e74705SXin Li } 110*67e74705SXin Li test7()111*67e74705SXin LiA test7() { 112*67e74705SXin Li A a1 = std::move(A()); 113*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 114*67e74705SXin Li // expected-note@-2{{remove std::move call}} 115*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 116*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" 117*67e74705SXin Li A a2 = std::move((A())); 118*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 119*67e74705SXin Li // expected-note@-2{{remove std::move call}} 120*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 121*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:"" 122*67e74705SXin Li A a3 = (std::move(A())); 123*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 124*67e74705SXin Li // expected-note@-2{{remove std::move call}} 125*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" 126*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:"" 127*67e74705SXin Li A a4 = (std::move((A()))); 128*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 129*67e74705SXin Li // expected-note@-2{{remove std::move call}} 130*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" 131*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:27}:"" 132*67e74705SXin Li 133*67e74705SXin Li return std::move(a1); 134*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 135*67e74705SXin Li // expected-note@-2{{remove std::move call}} 136*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 137*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:22-[[@LINE-4]]:23}:"" 138*67e74705SXin Li return std::move((a1)); 139*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 140*67e74705SXin Li // expected-note@-2{{remove std::move call}} 141*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 142*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:24-[[@LINE-4]]:25}:"" 143*67e74705SXin Li return (std::move(a1)); 144*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 145*67e74705SXin Li // expected-note@-2{{remove std::move call}} 146*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" 147*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" 148*67e74705SXin Li return (std::move((a1))); 149*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 150*67e74705SXin Li // expected-note@-2{{remove std::move call}} 151*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:21}:"" 152*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:26}:"" 153*67e74705SXin Li } 154*67e74705SXin Li 155*67e74705SXin Li #define wrap1(x) x 156*67e74705SXin Li #define wrap2(x) x 157*67e74705SXin Li 158*67e74705SXin Li // Macro test. Since the std::move call is outside the macro, it is 159*67e74705SXin Li // safe to suggest a fix-it. test8()160*67e74705SXin LiA test8() { 161*67e74705SXin Li A a; 162*67e74705SXin Li return std::move(a); 163*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 164*67e74705SXin Li // expected-note@-2{{remove std::move call}} 165*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 166*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:"" 167*67e74705SXin Li return std::move(wrap1(a)); 168*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 169*67e74705SXin Li // expected-note@-2{{remove std::move call}} 170*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 171*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:28-[[@LINE-4]]:29}:"" 172*67e74705SXin Li return std::move(wrap1(wrap2(a))); 173*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 174*67e74705SXin Li // expected-note@-2{{remove std::move call}} 175*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" 176*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:35-[[@LINE-4]]:36}:"" 177*67e74705SXin Li } 178*67e74705SXin Li 179*67e74705SXin Li #define test9 \ 180*67e74705SXin Li A test9() { \ 181*67e74705SXin Li A a; \ 182*67e74705SXin Li return std::move(a); \ 183*67e74705SXin Li } 184*67e74705SXin Li 185*67e74705SXin Li // Macro test. The std::call is inside the macro, so no fix-it is suggested. 186*67e74705SXin Li test9 187*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 188*67e74705SXin Li // CHECK-NOT: fix-it 189*67e74705SXin Li 190*67e74705SXin Li #define return_a return std::move(a) 191*67e74705SXin Li 192*67e74705SXin Li // Macro test. The std::call is inside the macro, so no fix-it is suggested. test10()193*67e74705SXin LiA test10() { 194*67e74705SXin Li A a; 195*67e74705SXin Li return_a; 196*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 197*67e74705SXin Li // CHECK-NOT: fix-it 198*67e74705SXin Li } 199*67e74705SXin Li 200*67e74705SXin Li namespace templates { 201*67e74705SXin Li struct A {}; 202*67e74705SXin Li struct B { B(A); }; 203*67e74705SXin Li 204*67e74705SXin Li // Warn once here since the type is not dependent. 205*67e74705SXin Li template <typename T> test1()206*67e74705SXin Li A test1() { 207*67e74705SXin Li A a; 208*67e74705SXin Li return std::move(a); 209*67e74705SXin Li // expected-warning@-1{{prevents copy elision}} 210*67e74705SXin Li // expected-note@-2{{remove std::move call}} 211*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:"" 212*67e74705SXin Li // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" 213*67e74705SXin Li } run_test1()214*67e74705SXin Li void run_test1() { 215*67e74705SXin Li test1<A>(); 216*67e74705SXin Li test1<B>(); 217*67e74705SXin Li } 218*67e74705SXin Li 219*67e74705SXin Li // T1 and T2 may not be the same, the warning may not always apply. 220*67e74705SXin Li template <typename T1, typename T2> test2()221*67e74705SXin Li T1 test2() { 222*67e74705SXin Li T2 t; 223*67e74705SXin Li return std::move(t); 224*67e74705SXin Li } run_test2()225*67e74705SXin Li void run_test2() { 226*67e74705SXin Li test2<A, A>(); 227*67e74705SXin Li test2<B, A>(); 228*67e74705SXin Li } 229*67e74705SXin Li } 230