1 // RUN: %check_clang_tidy %s modernize-use-auto %t -- -- \
2 // RUN:   -std=c++11 -I %S/Inputs/modernize-use-auto
3 
4 #include "containers.h"
5 
f_array()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 
f_deque()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 
f_forward_list()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 
f_list()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 
f_vector()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 
f_map()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 
f_multimap()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 
f_set()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 
f_multiset()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 
f_unordered_map()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 
f_unordered_multimap()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 
f_unordered_set()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 
f_unordered_multiset()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 
sugar()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 
initializer_list()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 
construction()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 
pointer_to_iterator()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 
loop()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 
cv_qualifiers()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 
cleanup()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 
declaration_lists()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