1 // RUN: %check_clang_tidy -std=c++11-or-later %s performance-no-automatic-move %t 2 3 struct Obj { 4 Obj(); 5 Obj(const Obj &); 6 Obj(Obj &&); 7 virtual ~Obj(); 8 }; 9 10 struct NonTemplate { 11 NonTemplate(const Obj &); 12 NonTemplate(Obj &&); 13 }; 14 15 template <typename T> struct TemplateCtorPair { 16 TemplateCtorPair(const T &); 17 TemplateCtorPair(T &&value); 18 }; 19 20 template <typename T> struct UrefCtor { 21 template <class U = T> UrefCtor(U &&value); 22 }; 23 24 template <typename T> 25 T Make(); 26 PositiveNonTemplate()27NonTemplate PositiveNonTemplate() { 28 const Obj obj = Make<Obj>(); 29 return obj; // selects `NonTemplate(const Obj&)` 30 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj' prevents 31 // automatic move [performance-no-automatic-move] 32 } 33 PositiveTemplateCtorPair()34TemplateCtorPair<Obj> PositiveTemplateCtorPair() { 35 const Obj obj = Make<Obj>(); 36 return obj; // selects `TemplateCtorPair(const T&)` 37 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj' prevents 38 // automatic move [performance-no-automatic-move] 39 } 40 PositiveUrefCtor()41UrefCtor<Obj> PositiveUrefCtor() { 42 const Obj obj = Make<Obj>(); 43 return obj; // selects `UrefCtor(const T&&)` 44 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj' prevents 45 // automatic move [performance-no-automatic-move] 46 } 47 PositiveCantNrvo(bool b)48Obj PositiveCantNrvo(bool b) { 49 const Obj obj1; 50 const Obj obj2; 51 if (b) { 52 return obj1; 53 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: constness of 'obj1' prevents automatic move [performance-no-automatic-move] 54 } 55 return obj2; 56 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: constness of 'obj2' prevents automatic move [performance-no-automatic-move] 57 } 58 59 // FIXME: Ideally we would warn here too. PositiveNonTemplateLifetimeExtension()60NonTemplate PositiveNonTemplateLifetimeExtension() { 61 const Obj &obj = Make<Obj>(); 62 return obj; 63 } 64 65 // FIXME: Ideally we would warn here too. PositiveUrefCtorLifetimeExtension()66UrefCtor<Obj> PositiveUrefCtorLifetimeExtension() { 67 const Obj &obj = Make<Obj>(); 68 return obj; 69 } 70 71 // Negatives. 72 Temporary()73UrefCtor<Obj> Temporary() { return Make<Obj>(); } 74 ConstTemporary()75UrefCtor<Obj> ConstTemporary() { return Make<const Obj>(); } 76 ConvertingMoveConstructor()77UrefCtor<Obj> ConvertingMoveConstructor() { 78 Obj obj = Make<Obj>(); 79 return obj; 80 } 81 ConstNrvo()82Obj ConstNrvo() { 83 const Obj obj = Make<Obj>(); 84 return obj; 85 } 86 NotNrvo(bool b)87Obj NotNrvo(bool b) { 88 Obj obj1; 89 Obj obj2; 90 if (b) { 91 return obj1; 92 } 93 return obj2; 94 } 95 Ref()96UrefCtor<Obj> Ref() { 97 Obj &obj = Make<Obj &>(); 98 return obj; 99 } 100 ConstRef()101UrefCtor<Obj> ConstRef() { 102 const Obj &obj = Make<Obj &>(); 103 return obj; 104 } 105 106 const Obj global; 107 Global()108UrefCtor<Obj> Global() { return global; } 109 110 struct FromConstRefOnly { 111 FromConstRefOnly(const Obj &); 112 }; 113 FromConstRefOnly()114FromConstRefOnly FromConstRefOnly() { 115 const Obj obj = Make<Obj>(); 116 return obj; 117 } 118