1 // RUN: %check_clang_tidy -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/modernize-use-auto
2 // FIXME: Fix the checker to work in C++17 mode.
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