1// RUN: %check_clang_tidy -std=c++11-or-later %s performance-no-automatic-move %t
2
3struct Obj {
4 Obj();
5 Obj(const Obj &);
6 Obj(Obj &&);
7 virtual ~Obj();
8};
9
10struct NonTemplate {
11 NonTemplate(const Obj &);
12 NonTemplate(Obj &&);
13};
14
15template <typename T> struct TemplateCtorPair {
16 TemplateCtorPair(const T &);
17 TemplateCtorPair(T &&value);
18};
19
20template <typename T> struct UrefCtor {
21 template <class U = T> UrefCtor(U &&value);
22};
23
24template <typename T>
25T Make();
26
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
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
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
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.
60NonTemplate PositiveNonTemplateLifetimeExtension() {
61 const Obj &obj = Make<Obj>();
62 return obj;
63}
64
65// FIXME: Ideally we would warn here too.
66UrefCtor<Obj> PositiveUrefCtorLifetimeExtension() {
67 const Obj &obj = Make<Obj>();
68 return obj;
69}
70
71// Negatives.
72
73UrefCtor<Obj> Temporary() { return Make<Obj>(); }
74
75UrefCtor<Obj> ConstTemporary() { return Make<const Obj>(); }
76
77UrefCtor<Obj> ConvertingMoveConstructor() {
78 Obj obj = Make<Obj>();
79 return obj;
80}
81
82Obj ConstNrvo() {
83 const Obj obj = Make<Obj>();
84 return obj;
85}
86
87Obj NotNrvo(bool b) {
88 Obj obj1;
89 Obj obj2;
90 if (b) {
91 return obj1;
92 }
93 return obj2;
94}
95
96UrefCtor<Obj> Ref() {
97 Obj &obj = Make<Obj &>();
98 return obj;
99}
100
101UrefCtor<Obj> ConstRef() {
102 const Obj &obj = Make<Obj &>();
103 return obj;
104}
105
106const Obj global;
107
108UrefCtor<Obj> Global() { return global; }
109
110struct FromConstRefOnly {
111 FromConstRefOnly(const Obj &);
112};
113
114FromConstRefOnly FromConstRefOnly() {
115 const Obj obj = Make<Obj>();
116 return obj;
117}
118

source code of clang-tools-extra/test/clang-tidy/checkers/performance/no-automatic-move.cpp