121583b73SAdam Balogh // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.InvalidatedIterator -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify
221583b73SAdam Balogh // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.InvalidatedIterator -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
32cfbe933SAdam Balogh 
42cfbe933SAdam Balogh #include "Inputs/system-header-simulator-cxx.h"
52cfbe933SAdam Balogh 
612f5c7f0SAdam Balogh void clang_analyzer_warnIfReached();
712f5c7f0SAdam Balogh 
normal_dereference(std::vector<int> & V)823022b93SAdam Balogh void normal_dereference(std::vector<int> &V) {
923022b93SAdam Balogh   auto i = V.cbegin();
1023022b93SAdam Balogh   *i; // no-warning
112cfbe933SAdam Balogh }
122cfbe933SAdam Balogh 
invalidated_dereference(std::vector<int> & V)1323022b93SAdam Balogh void invalidated_dereference(std::vector<int> &V) {
1423022b93SAdam Balogh   auto i = V.cbegin();
1523022b93SAdam Balogh   V.erase(i);
1623022b93SAdam Balogh   *i; // expected-warning{{Invalidated iterator accessed}}
172cfbe933SAdam Balogh }
182cfbe933SAdam Balogh 
normal_prefix_increment(std::vector<int> & V)1923022b93SAdam Balogh void normal_prefix_increment(std::vector<int> &V) {
2023022b93SAdam Balogh   auto i = V.cbegin();
2123022b93SAdam Balogh   ++i; // no-warning
222cfbe933SAdam Balogh }
232cfbe933SAdam Balogh 
invalidated_prefix_increment(std::vector<int> & V)2423022b93SAdam Balogh void invalidated_prefix_increment(std::vector<int> &V) {
2523022b93SAdam Balogh   auto i = V.cbegin();
2623022b93SAdam Balogh   V.erase(i);
2723022b93SAdam Balogh   ++i; // expected-warning{{Invalidated iterator accessed}}
282cfbe933SAdam Balogh }
299a48ba6bSAdam Balogh 
normal_prefix_decrement(std::vector<int> & V)3023022b93SAdam Balogh void normal_prefix_decrement(std::vector<int> &V) {
3123022b93SAdam Balogh   auto i = ++V.cbegin();
3223022b93SAdam Balogh   --i; // no-warning
332e7cb34dSAdam Balogh }
342e7cb34dSAdam Balogh 
invalidated_prefix_decrement(std::vector<int> & V)3523022b93SAdam Balogh void invalidated_prefix_decrement(std::vector<int> &V) {
3623022b93SAdam Balogh   auto i = ++V.cbegin();
3723022b93SAdam Balogh   V.erase(i);
3823022b93SAdam Balogh   --i; // expected-warning{{Invalidated iterator accessed}}
392e7cb34dSAdam Balogh }
402e7cb34dSAdam Balogh 
normal_postfix_increment(std::vector<int> & V)4123022b93SAdam Balogh void normal_postfix_increment(std::vector<int> &V) {
4223022b93SAdam Balogh   auto i = V.cbegin();
4323022b93SAdam Balogh   i++; // no-warning
442e7cb34dSAdam Balogh }
452e7cb34dSAdam Balogh 
invalidated_postfix_increment(std::vector<int> & V)4623022b93SAdam Balogh void invalidated_postfix_increment(std::vector<int> &V) {
4723022b93SAdam Balogh   auto i = V.cbegin();
4823022b93SAdam Balogh   V.erase(i);
4923022b93SAdam Balogh   i++; // expected-warning{{Invalidated iterator accessed}}
502e7cb34dSAdam Balogh }
512e7cb34dSAdam Balogh 
normal_postfix_decrement(std::vector<int> & V)5223022b93SAdam Balogh void normal_postfix_decrement(std::vector<int> &V) {
5323022b93SAdam Balogh   auto i = ++V.cbegin();
5423022b93SAdam Balogh   i--; // no-warning
552e7cb34dSAdam Balogh }
562e7cb34dSAdam Balogh 
invalidated_postfix_decrement(std::vector<int> & V)5723022b93SAdam Balogh void invalidated_postfix_decrement(std::vector<int> &V) {
5823022b93SAdam Balogh   auto i = ++V.cbegin();
5923022b93SAdam Balogh   V.erase(i);
6023022b93SAdam Balogh   i--; // expected-warning{{Invalidated iterator accessed}}
612e7cb34dSAdam Balogh }
622e7cb34dSAdam Balogh 
normal_increment_by_2(std::vector<int> & V)6323022b93SAdam Balogh void normal_increment_by_2(std::vector<int> &V) {
6423022b93SAdam Balogh   auto i = V.cbegin();
6523022b93SAdam Balogh   i += 2; // no-warning
6612f5c7f0SAdam Balogh }
6712f5c7f0SAdam Balogh 
invalidated_increment_by_2(std::vector<int> & V)6823022b93SAdam Balogh void invalidated_increment_by_2(std::vector<int> &V) {
6923022b93SAdam Balogh   auto i = V.cbegin();
7023022b93SAdam Balogh   V.erase(i);
7123022b93SAdam Balogh   i += 2; // expected-warning{{Invalidated iterator accessed}}
722e7cb34dSAdam Balogh }
732e7cb34dSAdam Balogh 
normal_increment_by_2_copy(std::vector<int> & V)7423022b93SAdam Balogh void normal_increment_by_2_copy(std::vector<int> &V) {
7523022b93SAdam Balogh   auto i = V.cbegin();
7623022b93SAdam Balogh   auto j = i + 2; // no-warning
7712f5c7f0SAdam Balogh }
7812f5c7f0SAdam Balogh 
invalidated_increment_by_2_copy(std::vector<int> & V)7923022b93SAdam Balogh void invalidated_increment_by_2_copy(std::vector<int> &V) {
8023022b93SAdam Balogh   auto i = V.cbegin();
8123022b93SAdam Balogh   V.erase(i);
8223022b93SAdam Balogh   auto j = i + 2; // expected-warning{{Invalidated iterator accessed}}
832e7cb34dSAdam Balogh }
842e7cb34dSAdam Balogh 
normal_decrement_by_2(std::vector<int> & V)8523022b93SAdam Balogh void normal_decrement_by_2(std::vector<int> &V) {
8623022b93SAdam Balogh   auto i = V.cbegin();
8723022b93SAdam Balogh   i -= 2; // no-warning
889a48ba6bSAdam Balogh }
899a48ba6bSAdam Balogh 
invalidated_decrement_by_2(std::vector<int> & V)9023022b93SAdam Balogh void invalidated_decrement_by_2(std::vector<int> &V) {
9123022b93SAdam Balogh   auto i = V.cbegin();
9223022b93SAdam Balogh   V.erase(i);
9323022b93SAdam Balogh   i -= 2; // expected-warning{{Invalidated iterator accessed}}
949a48ba6bSAdam Balogh }
959a48ba6bSAdam Balogh 
normal_decrement_by_2_copy(std::vector<int> & V)9623022b93SAdam Balogh void normal_decrement_by_2_copy(std::vector<int> &V) {
9723022b93SAdam Balogh   auto i = V.cbegin();
9823022b93SAdam Balogh   auto j = i - 2; // no-warning
999a48ba6bSAdam Balogh }
1009a48ba6bSAdam Balogh 
invalidated_decrement_by_2_copy(std::vector<int> & V)10123022b93SAdam Balogh void invalidated_decrement_by_2_copy(std::vector<int> &V) {
10223022b93SAdam Balogh   auto i = V.cbegin();
10323022b93SAdam Balogh   V.erase(i);
10423022b93SAdam Balogh   auto j = i - 2; // expected-warning{{Invalidated iterator accessed}}
10512f5c7f0SAdam Balogh }
10612f5c7f0SAdam Balogh 
normal_subscript(std::vector<int> & V)10723022b93SAdam Balogh void normal_subscript(std::vector<int> &V) {
10823022b93SAdam Balogh   auto i = V.cbegin();
10923022b93SAdam Balogh   i[1]; // no-warning
1109a48ba6bSAdam Balogh }
1119a48ba6bSAdam Balogh 
invalidated_subscript(std::vector<int> & V)11223022b93SAdam Balogh void invalidated_subscript(std::vector<int> &V) {
11323022b93SAdam Balogh   auto i = V.cbegin();
11423022b93SAdam Balogh   V.erase(i);
11523022b93SAdam Balogh   i[1]; // expected-warning{{Invalidated iterator accessed}}
1169a48ba6bSAdam Balogh }
1179a48ba6bSAdam Balogh 
assignment(std::vector<int> & V)11823022b93SAdam Balogh void assignment(std::vector<int> &V) {
11923022b93SAdam Balogh   auto i = V.cbegin();
12023022b93SAdam Balogh   V.erase(i);
12123022b93SAdam Balogh   auto j = V.cbegin(); // no-warning
12212f5c7f0SAdam Balogh }
123*9e63b190SAdam Balogh 
124*9e63b190SAdam Balogh template<typename T>
125*9e63b190SAdam Balogh struct cont_with_ptr_iterator {
126*9e63b190SAdam Balogh   T *begin() const;
127*9e63b190SAdam Balogh   T *end() const;
128*9e63b190SAdam Balogh   T &operator[](size_t);
129*9e63b190SAdam Balogh   void push_back(const T&);
130*9e63b190SAdam Balogh   T* erase(T*);
131*9e63b190SAdam Balogh };
132*9e63b190SAdam Balogh 
invalidated_dereference_end_ptr_iterator(cont_with_ptr_iterator<int> & C)133*9e63b190SAdam Balogh void invalidated_dereference_end_ptr_iterator(cont_with_ptr_iterator<int> &C) {
134*9e63b190SAdam Balogh   auto i = C.begin();
135*9e63b190SAdam Balogh   C.erase(i);
136*9e63b190SAdam Balogh   (void) *i; // expected-warning{{Invalidated iterator accessed}}
137*9e63b190SAdam Balogh }
138*9e63b190SAdam Balogh 
invalidated_prefix_increment_end_ptr_iterator(cont_with_ptr_iterator<int> & C)139*9e63b190SAdam Balogh void invalidated_prefix_increment_end_ptr_iterator(
140*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
141*9e63b190SAdam Balogh   auto i = C.begin();
142*9e63b190SAdam Balogh   C.erase(i);
143*9e63b190SAdam Balogh   ++i; // expected-warning{{Invalidated iterator accessed}}
144*9e63b190SAdam Balogh }
145*9e63b190SAdam Balogh 
invalidated_prefix_decrement_end_ptr_iterator(cont_with_ptr_iterator<int> & C)146*9e63b190SAdam Balogh void invalidated_prefix_decrement_end_ptr_iterator(
147*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
148*9e63b190SAdam Balogh   auto i = C.begin() + 1;
149*9e63b190SAdam Balogh   C.erase(i);
150*9e63b190SAdam Balogh   --i; // expected-warning{{Invalidated iterator accessed}}
151*9e63b190SAdam Balogh }
152*9e63b190SAdam Balogh 
invalidated_postfix_increment_end_ptr_iterator(cont_with_ptr_iterator<int> & C)153*9e63b190SAdam Balogh void invalidated_postfix_increment_end_ptr_iterator(
154*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
155*9e63b190SAdam Balogh   auto i = C.begin();
156*9e63b190SAdam Balogh   C.erase(i);
157*9e63b190SAdam Balogh   i++; // expected-warning{{Invalidated iterator accessed}}
158*9e63b190SAdam Balogh }
159*9e63b190SAdam Balogh 
invalidated_postfix_decrement_end_ptr_iterator(cont_with_ptr_iterator<int> & C)160*9e63b190SAdam Balogh void invalidated_postfix_decrement_end_ptr_iterator(
161*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
162*9e63b190SAdam Balogh   auto i = C.begin() + 1;
163*9e63b190SAdam Balogh   C.erase(i);
164*9e63b190SAdam Balogh   i--; // expected-warning{{Invalidated iterator accessed}}
165*9e63b190SAdam Balogh }
166*9e63b190SAdam Balogh 
invalidated_increment_by_2_end_ptr_iterator(cont_with_ptr_iterator<int> & C)167*9e63b190SAdam Balogh void invalidated_increment_by_2_end_ptr_iterator(
168*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
169*9e63b190SAdam Balogh   auto i = C.begin();
170*9e63b190SAdam Balogh   C.erase(i);
171*9e63b190SAdam Balogh   i += 2; // expected-warning{{Invalidated iterator accessed}}
172*9e63b190SAdam Balogh }
173*9e63b190SAdam Balogh 
invalidated_increment_by_2_copy_end_ptr_iterator(cont_with_ptr_iterator<int> & C)174*9e63b190SAdam Balogh void invalidated_increment_by_2_copy_end_ptr_iterator(
175*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
176*9e63b190SAdam Balogh   auto i = C.begin();
177*9e63b190SAdam Balogh   C.erase(i);
178*9e63b190SAdam Balogh   auto j = i + 2; // expected-warning{{Invalidated iterator accessed}}
179*9e63b190SAdam Balogh }
180*9e63b190SAdam Balogh 
invalidated_decrement_by_2_end_ptr_iterator(cont_with_ptr_iterator<int> & C)181*9e63b190SAdam Balogh void invalidated_decrement_by_2_end_ptr_iterator(
182*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
183*9e63b190SAdam Balogh   auto i = C.begin();
184*9e63b190SAdam Balogh   C.erase(i);
185*9e63b190SAdam Balogh   i -= 2; // expected-warning{{Invalidated iterator accessed}}
186*9e63b190SAdam Balogh }
187*9e63b190SAdam Balogh 
invalidated_decrement_by_2_copy_end_ptr_iterator(cont_with_ptr_iterator<int> & C)188*9e63b190SAdam Balogh void invalidated_decrement_by_2_copy_end_ptr_iterator(
189*9e63b190SAdam Balogh     cont_with_ptr_iterator<int> &C) {
190*9e63b190SAdam Balogh   auto i = C.begin();
191*9e63b190SAdam Balogh   C.erase(i);
192*9e63b190SAdam Balogh   auto j = i - 2; // expected-warning{{Invalidated iterator accessed}}
193*9e63b190SAdam Balogh }
194*9e63b190SAdam Balogh 
invalidated_subscript_end_ptr_iterator(cont_with_ptr_iterator<int> & C)195*9e63b190SAdam Balogh void invalidated_subscript_end_ptr_iterator(cont_with_ptr_iterator<int> &C) {
196*9e63b190SAdam Balogh   auto i = C.begin();
197*9e63b190SAdam Balogh   C.erase(i);
198*9e63b190SAdam Balogh   (void) i[1]; // expected-warning{{Invalidated iterator accessed}}
199*9e63b190SAdam Balogh }
200