1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify
2 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
3 
4 #include "Inputs/system-header-simulator-cxx.h"
5 
6 void clang_analyzer_warnIfReached();
7 
8 // Dereference - operator*()
9 
10 void deref_begin(const std::vector<int> &V) {
11   auto i = V.begin();
12   *i; // no-warning
13 }
14 
15 void deref_begind_begin(const std::vector<int> &V) {
16   auto i = ++V.begin();
17   *i; // no-warning
18 }
19 
20 template <typename Iter> Iter return_any_iterator(const Iter &It);
21 
22 void deref_unknown(const std::vector<int> &V) {
23   auto i = return_any_iterator(V.begin());
24   *i; // no-warning
25 }
26 
27 void deref_ahead_of_end(const std::vector<int> &V) {
28   auto i = --V.end();
29   *i; // no-warning
30 }
31 
32 void deref_end(const std::vector<int> &V) {
33   auto i = V.end();
34   *i; // expected-warning{{Past-the-end iterator dereferenced}}
35 }
36 
37 // Prefix increment - operator++()
38 
39 void incr_begin(const std::vector<int> &V) {
40   auto i = V.begin();
41   ++i; // no-warning
42 }
43 
44 void incr_behind_begin(const std::vector<int> &V) {
45   auto i = ++V.begin();
46   ++i; // no-warning
47 }
48 
49 void incr_unknown(const std::vector<int> &V) {
50   auto i = return_any_iterator(V.begin());
51   ++i; // no-warning
52 }
53 
54 void incr_ahead_of_end(const std::vector<int> &V) {
55   auto i = --V.end();
56   ++i; // no-warning
57 }
58 
59 void incr_end(const std::vector<int> &V) {
60   auto i = V.end();
61   ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
62 }
63 
64 // Postfix increment - operator++(int)
65 
66 void begin_incr(const std::vector<int> &V) {
67   auto i = V.begin();
68   i++; // no-warning
69 }
70 
71 void behind_begin_incr(const std::vector<int> &V) {
72   auto i = ++V.begin();
73   i++; // no-warning
74 }
75 
76 void unknown_incr(const std::vector<int> &V) {
77   auto i = return_any_iterator(V.begin());
78   i++; // no-warning
79 }
80 
81 void ahead_of_end_incr(const std::vector<int> &V) {
82   auto i = --V.end();
83   i++; // no-warning
84 }
85 
86 void end_incr(const std::vector<int> &V) {
87   auto i = V.end();
88   i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
89 }
90 
91 // Prefix decrement - operator--()
92 
93 void decr_begin(const std::vector<int> &V) {
94   auto i = V.begin();
95   --i; // expected-warning{{Iterator decremented ahead of its valid range}}
96 }
97 
98 void decr_behind_begin(const std::vector<int> &V) {
99   auto i = ++V.begin();
100   --i; // no-warning
101 }
102 
103 void decr_unknown(const std::vector<int> &V) {
104   auto i = return_any_iterator(V.begin());
105   --i; // no-warning
106 }
107 
108 void decr_ahead_of_end(const std::vector<int> &V) {
109   auto i = --V.end();
110   --i; // no-warning
111 }
112 
113 void decr_end(const std::vector<int> &V) {
114   auto i = V.end();
115   --i; // no-warning
116 }
117 
118 // Postfix decrement - operator--(int)
119 
120 void begin_decr(const std::vector<int> &V) {
121   auto i = V.begin();
122   i--; // expected-warning{{Iterator decremented ahead of its valid range}}
123 }
124 
125 void behind_begin_decr(const std::vector<int> &V) {
126   auto i = ++V.begin();
127   i--; // no-warning
128 }
129 
130 void unknown_decr(const std::vector<int> &V) {
131   auto i = return_any_iterator(V.begin());
132   i--; // no-warning
133 }
134 
135 void ahead_of_end_decr(const std::vector<int> &V) {
136   auto i = --V.end();
137   i--; // no-warning
138 }
139 
140 void end_decr(const std::vector<int> &V) {
141   auto i = V.end();
142   i--; // no-warning
143 }
144 
145 // Addition assignment - operator+=(int)
146 
147 void incr_by_2_begin(const std::vector<int> &V) {
148   auto i = V.begin();
149   i += 2; // no-warning
150 }
151 
152 void incr_by_2_behind_begin(const std::vector<int> &V) {
153   auto i = ++V.begin();
154   i += 2; // no-warning
155 }
156 
157 void incr_by_2_unknown(const std::vector<int> &V) {
158   auto i = return_any_iterator(V.begin());
159   i += 2; // no-warning
160 }
161 
162 void incr_by_2_ahead_by_2_of_end(const std::vector<int> &V) {
163   auto i = --V.end();
164   --i;
165   i += 2; // no-warning
166 }
167 
168 void incr_by_2_ahead_of_end(const std::vector<int> &V) {
169   auto i = --V.end();
170   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
171 }
172 
173 void incr_by_2_end(const std::vector<int> &V) {
174   auto i = V.end();
175   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
176 }
177 
178 // Addition - operator+(int)
179 
180 void incr_by_2_copy_begin(const std::vector<int> &V) {
181   auto i = V.begin();
182   auto j = i + 2; // no-warning
183 }
184 
185 void incr_by_2_copy_behind_begin(const std::vector<int> &V) {
186   auto i = ++V.begin();
187   auto j = i + 2; // no-warning
188 }
189 
190 void incr_by_2_copy_unknown(const std::vector<int> &V) {
191   auto i = return_any_iterator(V.begin());
192   auto j = i + 2; // no-warning
193 }
194 
195 void incr_by_2_copy_ahead_by_2_of_end(const std::vector<int> &V) {
196   auto i = --V.end();
197   --i;
198   auto j = i + 2; // no-warning
199 }
200 
201 void incr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
202   auto i = --V.end();
203   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
204 }
205 
206 void incr_by_2_copy_end(const std::vector<int> &V) {
207   auto i = V.end();
208   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
209 }
210 
211 // Subtraction assignment - operator-=(int)
212 
213 void decr_by_2_begin(const std::vector<int> &V) {
214   auto i = V.begin();
215   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
216 }
217 
218 void decr_by_2_behind_begin(const std::vector<int> &V) {
219   auto i = ++V.begin();
220   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
221 }
222 
223 void decr_by_2_behind_begin_by_2(const std::vector<int> &V) {
224   auto i = ++V.begin();
225   ++i;
226   i -= 2; // no-warning
227 }
228 
229 void decr_by_2_unknown(const std::vector<int> &V) {
230   auto i = return_any_iterator(V.begin());
231   i -= 2; // no-warning
232 }
233 
234 void decr_by_2_ahead_of_end(const std::vector<int> &V) {
235   auto i = --V.end();
236   i -= 2; // no-warning
237 }
238 
239 void decr_by_2_end(const std::vector<int> &V) {
240   auto i = V.end();
241   i -= 2; // no-warning
242 }
243 
244 // Subtraction - operator-(int)
245 
246 void decr_by_2_copy_begin(const std::vector<int> &V) {
247   auto i = V.begin();
248   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
249 }
250 
251 void decr_by_2_copy_behind_begin(const std::vector<int> &V) {
252   auto i = ++V.begin();
253   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
254 }
255 
256 void decr_by_2_copy_behind_begin_by_2(const std::vector<int> &V) {
257   auto i = ++V.begin();
258   ++i;
259   auto j = i - 2; // no-warning
260 }
261 
262 void decr_by_2_copy_unknown(const std::vector<int> &V) {
263   auto i = return_any_iterator(V.begin());
264   auto j = i - 2; // no-warning
265 }
266 
267 void decr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
268   auto i = --V.end();
269   auto j = i - 2; // no-warning
270 }
271 
272 void decr_by_2_copy_end(const std::vector<int> &V) {
273   auto i = V.end();
274   auto j = i - 2; // no-warning
275 }
276 
277 //
278 // Subscript - operator[](int)
279 //
280 
281 // By zero
282 
283 void subscript_zero_begin(const std::vector<int> &V) {
284   auto i = V.begin();
285   auto j = i[0]; // no-warning
286 }
287 
288 void subscript_zero_behind_begin(const std::vector<int> &V) {
289   auto i = ++V.begin();
290   auto j = i[0]; // no-warning
291 }
292 
293 void subscript_zero_unknown(const std::vector<int> &V) {
294   auto i = return_any_iterator(V.begin());
295   auto j = i[0]; // no-warning
296 }
297 
298 void subscript_zero_ahead_of_end(const std::vector<int> &V) {
299   auto i = --V.end();
300   auto j = i[0]; // no-warning
301 }
302 
303 void subscript_zero_end(const std::vector<int> &V) {
304   auto i = V.end();
305   auto j = i[0]; // expected-warning{{Past-the-end iterator dereferenced}}
306 }
307 
308 // By negative number
309 
310 void subscript_negative_begin(const std::vector<int> &V) {
311   auto i = V.begin();
312   auto j = i[-1]; // no-warning FIXME: expect warning Iterator decremented ahead of its valid range
313 }
314 
315 void subscript_negative_behind_begin(const std::vector<int> &V) {
316   auto i = ++V.begin();
317   auto j = i[-1]; // no-warning
318 }
319 
320 void subscript_negative_unknown(const std::vector<int> &V) {
321   auto i = return_any_iterator(V.begin());
322   auto j = i[-1]; // no-warning
323 }
324 
325 void subscript_negative_ahead_of_end(const std::vector<int> &V) {
326   auto i = --V.end();
327   auto j = i[-1]; // no-warning
328 }
329 
330 void subscript_negative_end(const std::vector<int> &V) {
331   auto i = V.end();
332   auto j = i[-1]; // // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning
333 }
334 
335 // By positive number
336 
337 void subscript_positive_begin(const std::vector<int> &V) {
338   auto i = V.begin();
339   auto j = i[1]; // no-warning
340 }
341 
342 void subscript_positive_behind_begin(const std::vector<int> &V) {
343   auto i = ++V.begin();
344   auto j = i[1]; // no-warning
345 }
346 
347 void subscript_positive_unknown(const std::vector<int> &V) {
348   auto i = return_any_iterator(V.begin());
349   auto j = i[1]; // no-warning
350 }
351 
352 void subscript_positive_ahead_of_end(const std::vector<int> &V) {
353   auto i = --V.end();
354   auto j = i[1]; // no-warning FIXME: expected warning Past-the-end iterator dereferenced
355 }
356 
357 void subscript_positive_end(const std::vector<int> &V) {
358   auto i = V.end();
359   auto j = i[1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect warning Iterator incremented behind the past-the-end iterator
360 }
361 
362 //
363 // Structure member dereference operators
364 //
365 
366 struct S {
367   int n;
368 };
369 
370 // Member dereference - operator->()
371 
372 void arrow_deref_begin(const std::vector<S> &V) {
373   auto i = V.begin();
374   int n = i->n; // no-warning
375 }
376 
377 void arrow_deref_end(const std::vector<S> &V) {
378   auto i = V.end();
379   int n = i->n; //  expected-warning{{Past-the-end iterator dereferenced}}
380 }
381