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