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