1 // 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
2 // 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
3 
4 #include "Inputs/system-header-simulator-cxx.h"
5 
6 void clang_analyzer_warnIfReached();
7 
8 void normal_dereference(std::vector<int> &V) {
9   auto i = V.cbegin();
10   *i; // no-warning
11 }
12 
13 void invalidated_dereference(std::vector<int> &V) {
14   auto i = V.cbegin();
15   V.erase(i);
16   *i; // expected-warning{{Invalidated iterator accessed}}
17 }
18 
19 void normal_prefix_increment(std::vector<int> &V) {
20   auto i = V.cbegin();
21   ++i; // no-warning
22 }
23 
24 void invalidated_prefix_increment(std::vector<int> &V) {
25   auto i = V.cbegin();
26   V.erase(i);
27   ++i; // expected-warning{{Invalidated iterator accessed}}
28 }
29 
30 void normal_prefix_decrement(std::vector<int> &V) {
31   auto i = ++V.cbegin();
32   --i; // no-warning
33 }
34 
35 void invalidated_prefix_decrement(std::vector<int> &V) {
36   auto i = ++V.cbegin();
37   V.erase(i);
38   --i; // expected-warning{{Invalidated iterator accessed}}
39 }
40 
41 void normal_postfix_increment(std::vector<int> &V) {
42   auto i = V.cbegin();
43   i++; // no-warning
44 }
45 
46 void invalidated_postfix_increment(std::vector<int> &V) {
47   auto i = V.cbegin();
48   V.erase(i);
49   i++; // expected-warning{{Invalidated iterator accessed}}
50 }
51 
52 void normal_postfix_decrement(std::vector<int> &V) {
53   auto i = ++V.cbegin();
54   i--; // no-warning
55 }
56 
57 void invalidated_postfix_decrement(std::vector<int> &V) {
58   auto i = ++V.cbegin();
59   V.erase(i);
60   i--; // expected-warning{{Invalidated iterator accessed}}
61 }
62 
63 void normal_increment_by_2(std::vector<int> &V) {
64   auto i = V.cbegin();
65   i += 2; // no-warning
66 }
67 
68 void invalidated_increment_by_2(std::vector<int> &V) {
69   auto i = V.cbegin();
70   V.erase(i);
71   i += 2; // expected-warning{{Invalidated iterator accessed}}
72 }
73 
74 void normal_increment_by_2_copy(std::vector<int> &V) {
75   auto i = V.cbegin();
76   auto j = i + 2; // no-warning
77 }
78 
79 void invalidated_increment_by_2_copy(std::vector<int> &V) {
80   auto i = V.cbegin();
81   V.erase(i);
82   auto j = i + 2; // expected-warning{{Invalidated iterator accessed}}
83 }
84 
85 void normal_decrement_by_2(std::vector<int> &V) {
86   auto i = V.cbegin();
87   i -= 2; // no-warning
88 }
89 
90 void invalidated_decrement_by_2(std::vector<int> &V) {
91   auto i = V.cbegin();
92   V.erase(i);
93   i -= 2; // expected-warning{{Invalidated iterator accessed}}
94 }
95 
96 void normal_decrement_by_2_copy(std::vector<int> &V) {
97   auto i = V.cbegin();
98   auto j = i - 2; // no-warning
99 }
100 
101 void invalidated_decrement_by_2_copy(std::vector<int> &V) {
102   auto i = V.cbegin();
103   V.erase(i);
104   auto j = i - 2; // expected-warning{{Invalidated iterator accessed}}
105 }
106 
107 void normal_subscript(std::vector<int> &V) {
108   auto i = V.cbegin();
109   i[1]; // no-warning
110 }
111 
112 void invalidated_subscript(std::vector<int> &V) {
113   auto i = V.cbegin();
114   V.erase(i);
115   i[1]; // expected-warning{{Invalidated iterator accessed}}
116 }
117 
118 void assignment(std::vector<int> &V) {
119   auto i = V.cbegin();
120   V.erase(i);
121   auto j = V.cbegin(); // no-warning
122 }
123