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