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