xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/performance/no-automatic-move.cpp (revision 9182c679dde7cb6480e66b9231a53d43ad03908b)
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()27 NonTemplate 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()34 TemplateCtorPair<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()41 UrefCtor<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)48 Obj 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()60 NonTemplate PositiveNonTemplateLifetimeExtension() {
61   const Obj &obj = Make<Obj>();
62   return obj;
63 }
64 
65 // FIXME: Ideally we would warn here too.
PositiveUrefCtorLifetimeExtension()66 UrefCtor<Obj> PositiveUrefCtorLifetimeExtension() {
67   const Obj &obj = Make<Obj>();
68   return obj;
69 }
70 
71 // Negatives.
72 
Temporary()73 UrefCtor<Obj> Temporary() { return Make<Obj>(); }
74 
ConstTemporary()75 UrefCtor<Obj> ConstTemporary() { return Make<const Obj>(); }
76 
ConvertingMoveConstructor()77 UrefCtor<Obj> ConvertingMoveConstructor() {
78   Obj obj = Make<Obj>();
79   return obj;
80 }
81 
ConstNrvo()82 Obj ConstNrvo() {
83   const Obj obj = Make<Obj>();
84   return obj;
85 }
86 
NotNrvo(bool b)87 Obj NotNrvo(bool b) {
88   Obj obj1;
89   Obj obj2;
90   if (b) {
91     return obj1;
92   }
93   return obj2;
94 }
95 
Ref()96 UrefCtor<Obj> Ref() {
97   Obj &obj = Make<Obj &>();
98   return obj;
99 }
100 
ConstRef()101 UrefCtor<Obj> ConstRef() {
102   const Obj &obj = Make<Obj &>();
103   return obj;
104 }
105 
106 const Obj global;
107 
Global()108 UrefCtor<Obj> Global() { return global; }
109 
110 struct FromConstRefOnly {
111   FromConstRefOnly(const Obj &);
112 };
113 
FromConstRefOnly()114 FromConstRefOnly FromConstRefOnly() {
115   const Obj obj = Make<Obj>();
116   return obj;
117 }
118