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

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp