xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/replace-auto-ptr.cpp (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/replace-auto-ptr
2*89a1d03eSRichard 
3*89a1d03eSRichard // CHECK-FIXES: #include <utility>
4*89a1d03eSRichard 
5*89a1d03eSRichard #include "memory.h"
6*89a1d03eSRichard 
7*89a1d03eSRichard // Instrumentation for auto_ptr_ref test.
8*89a1d03eSRichard struct Base {};
9*89a1d03eSRichard struct Derived : Base {};
10*89a1d03eSRichard std::auto_ptr<Derived> create_derived_ptr();
11*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated, use unique_ptr instead [modernize-replace-auto-ptr]
12*89a1d03eSRichard // CHECK-FIXES: std::unique_ptr<Derived> create_derived_ptr();
13*89a1d03eSRichard 
14*89a1d03eSRichard 
15*89a1d03eSRichard // Test function return values (declaration)
16*89a1d03eSRichard std::auto_ptr<char> f_5();
17*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
18*89a1d03eSRichard // CHECK-FIXES: std::unique_ptr<char> f_5()
19*89a1d03eSRichard 
20*89a1d03eSRichard 
21*89a1d03eSRichard // Test function parameters.
22*89a1d03eSRichard void f_6(std::auto_ptr<int>);
23*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
24*89a1d03eSRichard // CHECK-FIXES: void f_6(std::unique_ptr<int>);
25*89a1d03eSRichard void f_7(const std::auto_ptr<int> &);
26*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: auto_ptr is deprecated
27*89a1d03eSRichard // CHECK-FIXES: void f_7(const std::unique_ptr<int> &);
28*89a1d03eSRichard 
29*89a1d03eSRichard 
30*89a1d03eSRichard // Test on record type fields.
31*89a1d03eSRichard struct A {
32*89a1d03eSRichard   std::auto_ptr<int> field;
33*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
34*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> field;
35*89a1d03eSRichard 
36*89a1d03eSRichard   typedef std::auto_ptr<int> int_ptr_type;
37*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
38*89a1d03eSRichard   // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_type;
39*89a1d03eSRichard };
40*89a1d03eSRichard 
41*89a1d03eSRichard 
42*89a1d03eSRichard // FIXME: Test template WITH instantiation.
43*89a1d03eSRichard template <typename T> struct B {
44*89a1d03eSRichard   typedef typename std::auto_ptr<T> created_type;
45*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: auto_ptr is deprecated
46*89a1d03eSRichard   // CHECK-FIXES: typedef typename std::unique_ptr<T> created_type;
47*89a1d03eSRichard 
createB48*89a1d03eSRichard   created_type create() { return std::auto_ptr<T>(new T()); }
49*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: auto_ptr is deprecated
50*89a1d03eSRichard   // CHECK-FIXES: created_type create() { return std::unique_ptr<T>(new T()); }
51*89a1d03eSRichard };
52*89a1d03eSRichard 
53*89a1d03eSRichard 
54*89a1d03eSRichard // Test 'using' in a namespace (declaration)
55*89a1d03eSRichard namespace ns_1 {
56*89a1d03eSRichard // Test multiple using declarations.
57*89a1d03eSRichard   using std::auto_ptr;
58*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
59*89a1d03eSRichard   // CHECK-FIXES: using std::unique_ptr;
60*89a1d03eSRichard   using std::auto_ptr;
61*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
62*89a1d03eSRichard   // CHECK-FIXES: using std::unique_ptr;
63*89a1d03eSRichard }
64*89a1d03eSRichard 
65*89a1d03eSRichard 
66*89a1d03eSRichard namespace ns_2 {
67*89a1d03eSRichard template <typename T> struct auto_ptr {};
68*89a1d03eSRichard }
69*89a1d03eSRichard 
f_1()70*89a1d03eSRichard void f_1() {
71*89a1d03eSRichard   std::auto_ptr<int> a;
72*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
73*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> a;
74*89a1d03eSRichard 
75*89a1d03eSRichard   // Check that spaces aren't modified unnecessarily.
76*89a1d03eSRichard   std:: auto_ptr <int> b;
77*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
78*89a1d03eSRichard   // CHECK-FIXES: std:: unique_ptr <int> b;
79*89a1d03eSRichard   std :: auto_ptr < char > c(new char());
80*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: auto_ptr is deprecated
81*89a1d03eSRichard   // CHECK-FIXES: std :: unique_ptr < char > c(new char());
82*89a1d03eSRichard 
83*89a1d03eSRichard   // Test construction from a temporary.
84*89a1d03eSRichard   std::auto_ptr<char> d = std::auto_ptr<char>();
85*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
86*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: auto_ptr is deprecated
87*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<char> d = std::unique_ptr<char>();
88*89a1d03eSRichard 
89*89a1d03eSRichard   typedef std::auto_ptr<int> int_ptr_t;
90*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
91*89a1d03eSRichard   // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_t;
92*89a1d03eSRichard   int_ptr_t e(new int());
93*89a1d03eSRichard 
94*89a1d03eSRichard   // Test pointers.
95*89a1d03eSRichard   std::auto_ptr<int> *f;
96*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
97*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> *f;
98*89a1d03eSRichard 
99*89a1d03eSRichard   // Test 'static' declarations.
100*89a1d03eSRichard   static std::auto_ptr<int> g;
101*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
102*89a1d03eSRichard   // CHECK-FIXES: static std::unique_ptr<int> g;
103*89a1d03eSRichard 
104*89a1d03eSRichard   // Test with cv-qualifiers.
105*89a1d03eSRichard   const std::auto_ptr<int> h;
106*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
107*89a1d03eSRichard   // CHECK-FIXES: const std::unique_ptr<int> h;
108*89a1d03eSRichard   volatile std::auto_ptr<int> i;
109*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
110*89a1d03eSRichard   // CHECK-FIXES: volatile std::unique_ptr<int> i;
111*89a1d03eSRichard   const volatile std::auto_ptr<int> j;
112*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: auto_ptr is deprecated
113*89a1d03eSRichard   // CHECK-FIXES: const volatile std::unique_ptr<int> j;
114*89a1d03eSRichard 
115*89a1d03eSRichard   // Test auto and initializer-list.
116*89a1d03eSRichard   auto k = std::auto_ptr<int>{};
117*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
118*89a1d03eSRichard   // CHECK-FIXES: auto k = std::unique_ptr<int>{};
119*89a1d03eSRichard   std::auto_ptr<int> l{std::auto_ptr<int>()};
120*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
121*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: auto_ptr is deprecated
122*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> l{std::unique_ptr<int>()};
123*89a1d03eSRichard 
124*89a1d03eSRichard   // Test interlocked auto_ptr.
125*89a1d03eSRichard   std::auto_ptr<std::auto_ptr<int> > m;
126*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
127*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: auto_ptr is deprecated
128*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<std::unique_ptr<int> > m;
129*89a1d03eSRichard 
130*89a1d03eSRichard   // Test temporaries.
131*89a1d03eSRichard   std::auto_ptr<char>();
132*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
133*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<char>();
134*89a1d03eSRichard 
135*89a1d03eSRichard   // Test void-specialization.
136*89a1d03eSRichard   std::auto_ptr<void> n;
137*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
138*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<void> n;
139*89a1d03eSRichard 
140*89a1d03eSRichard   // Test template WITH instantiation (instantiation).
141*89a1d03eSRichard   B<double> o;
142*89a1d03eSRichard   std::auto_ptr<double> p(o.create());
143*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
144*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<double> p(o.create());
145*89a1d03eSRichard 
146*89a1d03eSRichard   // Test 'using' in a namespace ("definition").
147*89a1d03eSRichard   ns_1::auto_ptr<int> q;
148*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
149*89a1d03eSRichard   // CHECK-FIXES: ns_1::unique_ptr<int> q;
150*89a1d03eSRichard 
151*89a1d03eSRichard   // Test construction with an 'auto_ptr_ref'.
152*89a1d03eSRichard   std::auto_ptr<Base> r(create_derived_ptr());
153*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
154*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<Base> r(create_derived_ptr());
155*89a1d03eSRichard }
156*89a1d03eSRichard 
157*89a1d03eSRichard // Test without the nested name specifiers.
f_2()158*89a1d03eSRichard void f_2() {
159*89a1d03eSRichard   using namespace std;
160*89a1d03eSRichard 
161*89a1d03eSRichard   auto_ptr<int> a;
162*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
163*89a1d03eSRichard   // CHECK-FIXES: unique_ptr<int> a;
164*89a1d03eSRichard }
165*89a1d03eSRichard 
166*89a1d03eSRichard // Test using declaration.
f_3()167*89a1d03eSRichard void f_3() {
168*89a1d03eSRichard   using std::auto_ptr;
169*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
170*89a1d03eSRichard   // CHECK-FIXES: using std::unique_ptr;
171*89a1d03eSRichard 
172*89a1d03eSRichard   auto_ptr<int> a;
173*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
174*89a1d03eSRichard   // CHECK-FIXES: unique_ptr<int> a;
175*89a1d03eSRichard }
176*89a1d03eSRichard 
177*89a1d03eSRichard // Test messing-up with macros.
f_4()178*89a1d03eSRichard void f_4() {
179*89a1d03eSRichard #define MACRO_1 <char>
180*89a1d03eSRichard   std::auto_ptr MACRO_1 p(new char());
181*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
182*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr MACRO_1 p(new char());
183*89a1d03eSRichard #define MACRO_2 auto_ptr
184*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
185*89a1d03eSRichard   // CHECK-FIXES: #define MACRO_2 unique_ptr
186*89a1d03eSRichard   std::MACRO_2<int> q;
187*89a1d03eSRichard #define MACRO_3(Type) std::auto_ptr<Type>
188*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: auto_ptr is deprecated
189*89a1d03eSRichard   // CHECK-FIXES: #define MACRO_3(Type) std::unique_ptr<Type>
190*89a1d03eSRichard   MACRO_3(float)r(new float());
191*89a1d03eSRichard #define MACRO_4 std::auto_ptr
192*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: auto_ptr is deprecated
193*89a1d03eSRichard   // CHECK-FIXES: #define MACRO_4 std::unique_ptr
194*89a1d03eSRichard   using MACRO_4;
195*89a1d03eSRichard #undef MACRO_1
196*89a1d03eSRichard #undef MACRO_2
197*89a1d03eSRichard #undef MACRO_3
198*89a1d03eSRichard #undef MACRO_4
199*89a1d03eSRichard }
200*89a1d03eSRichard 
201*89a1d03eSRichard // Test function return values (definition).
f_5()202*89a1d03eSRichard std::auto_ptr<char> f_5()
203*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
204*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<char> f_5()
205*89a1d03eSRichard {
206*89a1d03eSRichard   // Test constructor.
207*89a1d03eSRichard   return std::auto_ptr<char>(new char());
208*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
209*89a1d03eSRichard   // CHECK-FIXES: return std::unique_ptr<char>(new char());
210*89a1d03eSRichard }
211*89a1d03eSRichard 
212*89a1d03eSRichard // Test that non-std auto_ptr aren't replaced.
f_8()213*89a1d03eSRichard void f_8() {
214*89a1d03eSRichard   ns_2::auto_ptr<char> a;
215*89a1d03eSRichard   using namespace ns_2;
216*89a1d03eSRichard   auto_ptr<int> b;
217*89a1d03eSRichard }
218*89a1d03eSRichard 
219*89a1d03eSRichard // Fail to modify when the template is never instantiated.
220*89a1d03eSRichard //
221*89a1d03eSRichard // This might not be an issue. If it's never used it doesn't really matter if
222*89a1d03eSRichard // it's changed or not. If it's a header and one of the source use it, then it
223*89a1d03eSRichard // will still be changed.
224*89a1d03eSRichard template <typename X>
f()225*89a1d03eSRichard void f() {
226*89a1d03eSRichard   std::auto_ptr<X> p;
227*89a1d03eSRichard }
228*89a1d03eSRichard 
229*89a1d03eSRichard // FIXME: Alias template could be replaced if a matcher existed.
230*89a1d03eSRichard namespace std {
231*89a1d03eSRichard template <typename T> using aaaaaaaa = auto_ptr<T>;
232*89a1d03eSRichard }
233*89a1d03eSRichard 
234*89a1d03eSRichard // We want to avoid replacing 'aaaaaaaa' by unique_ptr here. It's better to
235*89a1d03eSRichard // change the type alias directly.
236*89a1d03eSRichard std::aaaaaaaa<int> d;
237*89a1d03eSRichard 
238*89a1d03eSRichard 
239*89a1d03eSRichard void takes_ownership_fn(std::auto_ptr<int> x);
240*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: auto_ptr is deprecated
241*89a1d03eSRichard // CHECK-FIXES: void takes_ownership_fn(std::unique_ptr<int> x);
242*89a1d03eSRichard 
243*89a1d03eSRichard std::auto_ptr<int> get_by_value();
244*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
245*89a1d03eSRichard // CHECK-FIXES: std::unique_ptr<int> get_by_value();
246*89a1d03eSRichard 
247*89a1d03eSRichard class Wrapper {
248*89a1d03eSRichard  public:
249*89a1d03eSRichard   std::auto_ptr<int> &get_wrapped();
250*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
251*89a1d03eSRichard 
252*89a1d03eSRichard  private:
253*89a1d03eSRichard   std::auto_ptr<int> wrapped;
254*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
255*89a1d03eSRichard };
256*89a1d03eSRichard 
f()257*89a1d03eSRichard void f() {
258*89a1d03eSRichard   std::auto_ptr<int> a, b, c;
259*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
260*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> a, b, c;
261*89a1d03eSRichard   Wrapper wrapper_a, wrapper_b;
262*89a1d03eSRichard 
263*89a1d03eSRichard   a = b;
264*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::move to transfer ownership
265*89a1d03eSRichard   // CHECK-FIXES: a = std::move(b);
266*89a1d03eSRichard 
267*89a1d03eSRichard   wrapper_a.get_wrapped() = wrapper_b.get_wrapped();
268*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::move to transfer ownership
269*89a1d03eSRichard   // CHECK-FIXES: wrapper_a.get_wrapped() = std::move(wrapper_b.get_wrapped());
270*89a1d03eSRichard 
271*89a1d03eSRichard   // Test that 'std::move()' is inserted when call to the
272*89a1d03eSRichard   // copy-constructor are made.
273*89a1d03eSRichard   takes_ownership_fn(c);
274*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
275*89a1d03eSRichard   // CHECK-FIXES: takes_ownership_fn(std::move(c));
276*89a1d03eSRichard   takes_ownership_fn(wrapper_a.get_wrapped());
277*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
278*89a1d03eSRichard   // CHECK-FIXES: takes_ownership_fn(std::move(wrapper_a.get_wrapped()));
279*89a1d03eSRichard 
280*89a1d03eSRichard   std::auto_ptr<int> d[] = { std::auto_ptr<int>(new int(1)),
281*89a1d03eSRichard                              std::auto_ptr<int>(new int(2)) };
282*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: auto_ptr is deprecated
283*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
284*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
285*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> d[] = { std::unique_ptr<int>(new int(1)),
286*89a1d03eSRichard   // CHECK-FIXES-NEXT:                         std::unique_ptr<int>(new int(2)) };
287*89a1d03eSRichard   std::auto_ptr<int> e = d[0];
288*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
289*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use std::move to transfer ownership
290*89a1d03eSRichard   // CHECK: std::unique_ptr<int> e = std::move(d[0]);
291*89a1d03eSRichard 
292*89a1d03eSRichard   // Test that std::move() is not used when assigning an rvalue
293*89a1d03eSRichard   std::auto_ptr<int> f;
294*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
295*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> f;
296*89a1d03eSRichard   f = std::auto_ptr<int>(new int(0));
297*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: auto_ptr is deprecated
298*89a1d03eSRichard   // CHECK-NEXT: f = std::unique_ptr<int>(new int(0));
299*89a1d03eSRichard 
300*89a1d03eSRichard   std::auto_ptr<int> g = get_by_value();
301*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
302*89a1d03eSRichard   // CHECK-FIXES: std::unique_ptr<int> g = get_by_value();
303*89a1d03eSRichard }
304