1 | // RUN: %check_clang_tidy -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/use-auto |
2 | // FIXME: Fix the checker to work in C++17 mode. |
3 | |
4 | #include "containers.h" |
5 | |
6 | void f_array() { |
7 | std::array<int, 4> C; |
8 | std::array<int, 4>::iterator ArrayI1 = C.begin(); |
9 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators [modernize-use-auto] |
10 | // CHECK-FIXES: auto ArrayI1 = C.begin(); |
11 | |
12 | std::array<int, 5>::reverse_iterator ArrayI2 = C.rbegin(); |
13 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
14 | // CHECK-FIXES: auto ArrayI2 = C.rbegin(); |
15 | |
16 | const std::array<int, 3> D; |
17 | std::array<int, 3>::const_iterator ArrayI3 = D.begin(); |
18 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
19 | // CHECK-FIXES: auto ArrayI3 = D.begin(); |
20 | |
21 | std::array<int, 5>::const_reverse_iterator ArrayI4 = D.rbegin(); |
22 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
23 | // CHECK-FIXES: auto ArrayI4 = D.rbegin(); |
24 | } |
25 | |
26 | void f_deque() { |
27 | std::deque<int> C; |
28 | std::deque<int>::iterator DequeI1 = C.begin(); |
29 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
30 | // CHECK-FIXES: auto DequeI1 = C.begin(); |
31 | |
32 | std::deque<int>::reverse_iterator DequeI2 = C.rbegin(); |
33 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
34 | // CHECK-FIXES: auto DequeI2 = C.rbegin(); |
35 | |
36 | const std::deque<int> D; |
37 | std::deque<int>::const_iterator DequeI3 = D.begin(); |
38 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
39 | // CHECK-FIXES: auto DequeI3 = D.begin(); |
40 | |
41 | std::deque<int>::const_reverse_iterator DequeI4 = D.rbegin(); |
42 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
43 | // CHECK-FIXES: auto DequeI4 = D.rbegin(); |
44 | } |
45 | |
46 | void f_forward_list() { |
47 | std::forward_list<int> C; |
48 | std::forward_list<int>::iterator FListI1 = C.begin(); |
49 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
50 | // CHECK-FIXES: auto FListI1 = C.begin(); |
51 | |
52 | const std::forward_list<int> D; |
53 | std::forward_list<int>::const_iterator FListI2 = D.begin(); |
54 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
55 | // CHECK-FIXES: auto FListI2 = D.begin(); |
56 | } |
57 | |
58 | void f_list() { |
59 | std::list<int> C; |
60 | std::list<int>::iterator ListI1 = C.begin(); |
61 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
62 | // CHECK-FIXES: auto ListI1 = C.begin(); |
63 | std::list<int>::reverse_iterator ListI2 = C.rbegin(); |
64 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
65 | // CHECK-FIXES: auto ListI2 = C.rbegin(); |
66 | |
67 | const std::list<int> D; |
68 | std::list<int>::const_iterator ListI3 = D.begin(); |
69 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
70 | // CHECK-FIXES: auto ListI3 = D.begin(); |
71 | std::list<int>::const_reverse_iterator ListI4 = D.rbegin(); |
72 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
73 | // CHECK-FIXES: auto ListI4 = D.rbegin(); |
74 | } |
75 | |
76 | void f_vector() { |
77 | std::vector<int> C; |
78 | std::vector<int>::iterator VecI1 = C.begin(); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
80 | // CHECK-FIXES: auto VecI1 = C.begin(); |
81 | |
82 | std::vector<int>::reverse_iterator VecI2 = C.rbegin(); |
83 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
84 | // CHECK-FIXES: auto VecI2 = C.rbegin(); |
85 | |
86 | const std::vector<int> D; |
87 | std::vector<int>::const_iterator VecI3 = D.begin(); |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
89 | // CHECK-FIXES: auto VecI3 = D.begin(); |
90 | |
91 | std::vector<int>::const_reverse_iterator VecI4 = D.rbegin(); |
92 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
93 | // CHECK-FIXES: auto VecI4 = D.rbegin(); |
94 | } |
95 | |
96 | void f_map() { |
97 | std::map<int, int> C; |
98 | std::map<int, int>::iterator MapI1 = C.begin(); |
99 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
100 | // CHECK-FIXES: auto MapI1 = C.begin(); |
101 | |
102 | std::map<int, int>::reverse_iterator MapI2 = C.rbegin(); |
103 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
104 | // CHECK-FIXES: auto MapI2 = C.rbegin(); |
105 | |
106 | const std::map<int, int> D; |
107 | std::map<int, int>::const_iterator MapI3 = D.begin(); |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
109 | // CHECK-FIXES: auto MapI3 = D.begin(); |
110 | |
111 | std::map<int, int>::const_reverse_iterator MapI4 = D.rbegin(); |
112 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
113 | // CHECK-FIXES: auto MapI4 = D.rbegin(); |
114 | } |
115 | |
116 | void f_multimap() { |
117 | std::multimap<int, int> C; |
118 | std::multimap<int, int>::iterator MMapI1 = C.begin(); |
119 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
120 | // CHECK-FIXES: auto MMapI1 = C.begin(); |
121 | |
122 | std::multimap<int, int>::reverse_iterator MMapI2 = C.rbegin(); |
123 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
124 | // CHECK-FIXES: auto MMapI2 = C.rbegin(); |
125 | |
126 | const std::multimap<int, int> D; |
127 | std::multimap<int, int>::const_iterator MMapI3 = D.begin(); |
128 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
129 | // CHECK-FIXES: auto MMapI3 = D.begin(); |
130 | |
131 | std::multimap<int, int>::const_reverse_iterator MMapI4 = D.rbegin(); |
132 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
133 | // CHECK-FIXES: auto MMapI4 = D.rbegin(); |
134 | } |
135 | |
136 | void f_set() { |
137 | std::set<int> C; |
138 | std::set<int>::iterator SetI1 = C.begin(); |
139 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
140 | // CHECK-FIXES: auto SetI1 = C.begin(); |
141 | |
142 | std::set<int>::reverse_iterator SetI2 = C.rbegin(); |
143 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
144 | // CHECK-FIXES: auto SetI2 = C.rbegin(); |
145 | |
146 | const std::set<int> D; |
147 | std::set<int>::const_iterator SetI3 = D.begin(); |
148 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
149 | // CHECK-FIXES: auto SetI3 = D.begin(); |
150 | |
151 | std::set<int>::const_reverse_iterator SetI4 = D.rbegin(); |
152 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
153 | // CHECK-FIXES: auto SetI4 = D.rbegin(); |
154 | } |
155 | |
156 | void f_multiset() { |
157 | std::multiset<int> C; |
158 | std::multiset<int>::iterator MSetI1 = C.begin(); |
159 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
160 | // CHECK-FIXES: auto MSetI1 = C.begin(); |
161 | |
162 | std::multiset<int>::reverse_iterator MSetI2 = C.rbegin(); |
163 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
164 | // CHECK-FIXES: auto MSetI2 = C.rbegin(); |
165 | |
166 | const std::multiset<int> D; |
167 | std::multiset<int>::const_iterator MSetI3 = D.begin(); |
168 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
169 | // CHECK-FIXES: auto MSetI3 = D.begin(); |
170 | |
171 | std::multiset<int>::const_reverse_iterator MSetI4 = D.rbegin(); |
172 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
173 | // CHECK-FIXES: auto MSetI4 = D.rbegin(); |
174 | } |
175 | |
176 | void f_unordered_map() { |
177 | std::unordered_map<int, int> C; |
178 | std::unordered_map<int, int>::iterator UMapI1 = C.begin(); |
179 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
180 | // CHECK-FIXES: auto UMapI1 = C.begin(); |
181 | |
182 | const std::unordered_map<int, int> D; |
183 | std::unordered_map<int, int>::const_iterator UMapI2 = D.begin(); |
184 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
185 | // CHECK-FIXES: auto UMapI2 = D.begin(); |
186 | } |
187 | |
188 | void f_unordered_multimap() { |
189 | std::unordered_multimap<int, int> C; |
190 | std::unordered_multimap<int, int>::iterator UMMapI1 = C.begin(); |
191 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
192 | // CHECK-FIXES: auto UMMapI1 = C.begin(); |
193 | |
194 | const std::unordered_multimap<int, int> D; |
195 | std::unordered_multimap<int, int>::const_iterator UMMapI2 = D.begin(); |
196 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
197 | // CHECK-FIXES: auto UMMapI2 = D.begin(); |
198 | } |
199 | |
200 | void f_unordered_set() { |
201 | std::unordered_set<int> C; |
202 | std::unordered_set<int>::iterator USetI1 = C.begin(); |
203 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
204 | // CHECK-FIXES: auto USetI1 = C.begin(); |
205 | |
206 | const std::unordered_set<int> D; |
207 | std::unordered_set<int>::const_iterator USetI2 = D.begin(); |
208 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
209 | // CHECK-FIXES: auto USetI2 = D.begin(); |
210 | } |
211 | |
212 | void f_unordered_multiset() { |
213 | std::unordered_multiset<int> C; |
214 | std::unordered_multiset<int>::iterator UMSetI1 = C.begin(); |
215 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
216 | // CHECK-FIXES: auto UMSetI1 = C.begin(); |
217 | |
218 | const std::unordered_multiset<int> D; |
219 | std::unordered_multiset<int>::const_iterator UMSetI2 = D.begin(); |
220 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
221 | // CHECK-FIXES: auto UMSetI2 = D.begin(); |
222 | } |
223 | |
224 | typedef std::vector<int>::iterator int_iterator; |
225 | |
226 | std::vector<int> Vec; |
227 | std::unordered_map<int, int> Map; |
228 | |
229 | void sugar() { |
230 | // Types with more sugar should work. Types with less should not. |
231 | int_iterator more_sugar = Vec.begin(); |
232 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
233 | // CHECK-FIXES: auto more_sugar = Vec.begin(); |
234 | } |
235 | |
236 | void initializer_list() { |
237 | // Initialization from initializer lists isn't allowed. Using 'auto' would |
238 | // result in std::initializer_list being deduced for the type. |
239 | std::unordered_map<int, int>::iterator I{Map.begin()}; |
240 | std::unordered_map<int, int>::iterator I2 = {Map.begin()}; |
241 | } |
242 | |
243 | void construction() { |
244 | // Various forms of construction. Default constructors and constructors with |
245 | // all-default parameters shouldn't get transformed. Construction from other |
246 | // types is also not allowed. |
247 | |
248 | std::unordered_map<int, int>::iterator copy(Map.begin()); |
249 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
250 | // CHECK-FIXES: auto copy(Map.begin()); |
251 | |
252 | std::unordered_map<int, int>::iterator def; |
253 | std::unordered_map<int, int>::const_iterator constI; |
254 | |
255 | // Implicit conversion. |
256 | std::unordered_map<int, int>::const_iterator constI2 = def; |
257 | std::unordered_map<int, int>::const_iterator constI3(def); |
258 | |
259 | // Explicit conversion |
260 | std::unordered_map<int, int>::const_iterator constI4 |
261 | = std::unordered_map<int, int>::const_iterator(def); |
262 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use auto when declaring iterators |
263 | // CHECK-FIXES: auto constI4 |
264 | // CHECK-FIXES-NEXT: = std::unordered_map<int, int>::const_iterator(def); |
265 | } |
266 | |
267 | void pointer_to_iterator() { |
268 | int_iterator I = Vec.begin(); |
269 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
270 | // CHECK-FIXES: auto I = Vec.begin(); |
271 | |
272 | // Pointers and references to iterators are not transformed. |
273 | int_iterator *IPtr = &I; |
274 | int_iterator &IRef = I; |
275 | } |
276 | |
277 | void loop() { |
278 | for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) { |
279 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators |
280 | // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I) |
281 | } |
282 | |
283 | for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) { |
284 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators |
285 | // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I) |
286 | } |
287 | |
288 | std::vector<std::vector<int>::iterator> IterVec; |
289 | for (std::vector<int>::iterator I : IterVec) { |
290 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators |
291 | // CHECK-FIXES: for (auto I : IterVec) |
292 | } |
293 | } |
294 | |
295 | void cv_qualifiers() { |
296 | // Make sure references and cv qualifiers don't get removed (i.e. replaced |
297 | // with just 'auto'). |
298 | const auto & I = Vec.begin(); |
299 | auto && I2 = Vec.begin(); |
300 | } |
301 | |
302 | void cleanup() { |
303 | // Passing a string as an argument to introduce a temporary object that will |
304 | // create an expression with cleanups. |
305 | std::map<std::string, int> MapFind; |
306 | std::map<std::string, int>::iterator I = MapFind.find("foo" ); |
307 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
308 | // CHECK-FIXES: auto I = MapFind.find("foo"); |
309 | } |
310 | |
311 | void declaration_lists() { |
312 | // Declaration lists that match the declaration type with written no-list |
313 | // initializer are transformed. |
314 | std::vector<int>::iterator I = Vec.begin(), E = Vec.end(); |
315 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators |
316 | // CHECK-FIXES: auto I = Vec.begin(), E = Vec.end(); |
317 | |
318 | // Declaration lists with non-initialized variables should not be transformed. |
319 | std::vector<int>::iterator J = Vec.begin(), K; |
320 | } |
321 | |