1 // RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -I %S/Inputs/modernize-smart-ptr
2
3 #include "shared_ptr.h"
4 // CHECK-FIXES: #include <memory>
5
6 struct Base {
7 Base();
8 Base(int, int);
9 };
10
11 struct Derived : public Base {
12 Derived();
13 Derived(int, int);
14 };
15
16 struct APair {
17 int a, b;
18 };
19
20 struct DPair {
DPairDPair21 DPair() : a(0), b(0) {}
DPairDPair22 DPair(int x, int y) : a(y), b(x) {}
23 int a, b;
24 };
25
26 struct Empty {};
27
28 template <class T>
29 using shared_ptr_ = std::shared_ptr<T>;
30
31 void *operator new(__SIZE_TYPE__ Count, void *Ptr);
32
33 int g(std::shared_ptr<int> P);
34
getPointer()35 std::shared_ptr<Base> getPointer() {
36 return std::shared_ptr<Base>(new Base);
37 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead
38 // CHECK-FIXES: return std::make_shared<Base>();
39 }
40
basic()41 void basic() {
42 std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
43 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
44 // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();
45
46 P1.reset(new int());
47 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
48 // CHECK-FIXES: P1 = std::make_shared<int>();
49
50 P1 = std::shared_ptr<int>(new int());
51 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
52 // CHECK-FIXES: P1 = std::make_shared<int>();
53
54 // Without parenthesis.
55 std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);
56 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
57 // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>();
58
59 P2.reset(new int);
60 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
61 // CHECK-FIXES: P2 = std::make_shared<int>();
62
63 P2 = std::shared_ptr<int>(new int);
64 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
65 // CHECK-FIXES: P2 = std::make_shared<int>();
66
67 // With auto.
68 auto P3 = std::shared_ptr<int>(new int());
69 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
70 // CHECK-FIXES: auto P3 = std::make_shared<int>();
71
72 std::shared_ptr<int> P4 = std::shared_ptr<int>((new int));
73 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
74 // CHECK-FIXES: std::shared_ptr<int> P4 = std::make_shared<int>();
75
76 P4.reset((((new int()))));
77 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
78 // CHECK-FIXES: P4 = std::make_shared<int>();
79
80 P4 = std::shared_ptr<int>(((new int)));
81 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
82 // CHECK-FIXES: P4 = std::make_shared<int>();
83
84 {
85 // No std.
86 using namespace std;
87 shared_ptr<int> Q = shared_ptr<int>(new int());
88 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead
89 // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();
90
91 Q = shared_ptr<int>(new int());
92 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
93 // CHECK-FIXES: Q = std::make_shared<int>();
94 }
95
96 std::shared_ptr<int> R(new int());
97
98 // Create the shared_ptr as a parameter to a function.
99 int T = g(std::shared_ptr<int>(new int()));
100 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
101 // CHECK-FIXES: int T = g(std::make_shared<int>());
102
103 // Only replace if the type in the template is the same as the type returned
104 // by the new operator.
105 auto Pderived = std::shared_ptr<Base>(new Derived());
106
107 // OK to replace for reset and assign
108 Pderived.reset(new Derived());
109 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead
110 // CHECK-FIXES: Pderived = std::make_shared<Derived>();
111
112 Pderived = std::shared_ptr<Derived>(new Derived());
113 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead
114 // CHECK-FIXES: Pderived = std::make_shared<Derived>();
115
116 // FIXME: OK to replace if assigned to shared_ptr<Base>
117 Pderived = std::shared_ptr<Base>(new Derived());
118
119 // FIXME: OK to replace when auto is not used
120 std::shared_ptr<Base> PBase = std::shared_ptr<Base>(new Derived());
121
122 // The pointer is returned by the function, nothing to do.
123 std::shared_ptr<Base> RetPtr = getPointer();
124
125 // This emulates std::move.
126 std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);
127
128 // Placement arguments should not be removed.
129 int *PInt = new int;
130 std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
131 Placement.reset(new (PInt) int{3});
132 Placement = std::shared_ptr<int>(new (PInt) int{3});
133 }
134
135 // Calling make_smart_ptr from within a member function of a type with a
136 // private or protected constructor would be ill-formed.
137 class Private {
138 private:
Private(int z)139 Private(int z) {}
140
141 public:
Private()142 Private() {}
create()143 void create() {
144 auto callsPublic = std::shared_ptr<Private>(new Private);
145 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
146 // CHECK-FIXES: auto callsPublic = std::make_shared<Private>();
147 auto ptr = std::shared_ptr<Private>(new Private(42));
148 ptr.reset(new Private(42));
149 ptr = std::shared_ptr<Private>(new Private(42));
150 }
151
152 virtual ~Private();
153 };
154
155 class Protected {
156 protected:
Protected()157 Protected() {}
158
159 public:
Protected(int,int)160 Protected(int, int) {}
create()161 void create() {
162 auto callsPublic = std::shared_ptr<Protected>(new Protected(1, 2));
163 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
164 // CHECK-FIXES: auto callsPublic = std::make_shared<Protected>(1, 2);
165 auto ptr = std::shared_ptr<Protected>(new Protected);
166 ptr.reset(new Protected);
167 ptr = std::shared_ptr<Protected>(new Protected);
168 }
169 };
170
initialization(int T,Base b)171 void initialization(int T, Base b) {
172 // Test different kinds of initialization of the pointee.
173
174 // Direct initialization with parenthesis.
175 std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));
176 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
177 // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);
178 PDir1.reset(new DPair(1, T));
179 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
180 // CHECK-FIXES: PDir1 = std::make_shared<DPair>(1, T);
181
182 // Direct initialization with braces.
183 std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});
184 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
185 // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);
186 PDir2.reset(new DPair{2, T});
187 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
188 // CHECK-FIXES: PDir2 = std::make_shared<DPair>(2, T);
189
190 // Aggregate initialization.
191 std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});
192 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
193 // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
194 PAggr.reset(new APair{T, 1});
195 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
196 // CHECK-FIXES: std::make_shared<APair>(APair{T, 1});
197
198 // Test different kinds of initialization of the pointee, when the shared_ptr
199 // is initialized with braces.
200
201 // Direct initialization with parenthesis.
202 std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)};
203 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
204 // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T);
205
206 // Direct initialization with braces.
207 std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}};
208 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
209 // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T);
210
211 // Aggregate initialization.
212 std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}};
213 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
214 // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2});
215
216 // Direct initialization with parenthesis, without arguments.
217 std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair());
218 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
219 // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>();
220
221 // Direct initialization with braces, without arguments.
222 std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{});
223 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
224 // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>();
225
226 // Aggregate initialization without arguments.
227 std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{});
228 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
229 // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{});
230 }
231
aliases()232 void aliases() {
233 typedef std::shared_ptr<int> IntPtr;
234 IntPtr Typedef = IntPtr(new int);
235 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead
236 // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>();
237
238 // We use 'bool' instead of '_Bool'.
239 typedef std::shared_ptr<bool> BoolPtr;
240 BoolPtr BoolType = BoolPtr(new bool);
241 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead
242 // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>();
243
244 // We use 'Base' instead of 'struct Base'.
245 typedef std::shared_ptr<Base> BasePtr;
246 BasePtr StructType = BasePtr(new Base);
247 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
248 // CHECK-FIXES: BasePtr StructType = std::make_shared<Base>();
249
250 #define PTR shared_ptr<int>
251 std::shared_ptr<int> Macro = std::PTR(new int);
252 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
253 // CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>();
254 #undef PTR
255
256 std::shared_ptr<int> Using = shared_ptr_<int>(new int);
257 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
258 // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>();
259 }
260
whitespaces()261 void whitespaces() {
262 // clang-format off
263 auto Space = std::shared_ptr <int>(new int());
264 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead
265 // CHECK-FIXES: auto Space = std::make_shared<int>();
266
267 auto Spaces = std :: shared_ptr <int>(new int());
268 // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead
269 // CHECK-FIXES: auto Spaces = std::make_shared<int>();
270 // clang-format on
271 }
272
nesting()273 void nesting() {
274 auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));
275 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead
276 // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);
277 Nest.reset(new std::shared_ptr<int>(new int));
278 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead
279 // CHECK-FIXES: Nest = std::make_shared<std::shared_ptr<int>>(new int);
280 Nest->reset(new int);
281 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
282 // CHECK-FIXES: *Nest = std::make_shared<int>();
283 }
284
reset()285 void reset() {
286 std::shared_ptr<int> P;
287 P.reset();
288 P.reset(nullptr);
289 P.reset(new int());
290 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_shared instead
291 // CHECK-FIXES: P = std::make_shared<int>();
292
293 auto Q = &P;
294 Q->reset(new int());
295 // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead
296 // CHECK-FIXES: *Q = std::make_shared<int>();
297 }
298