• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -analyzer-output=text -verify
2 
3 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -analyzer-output=text -verify
4 
5 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s
6 
7 #include "Inputs/system-header-simulator-cxx.h"
8 
9 template <typename Container>
10 long clang_analyzer_container_begin(const Container&);
11 template <typename Container>
12 long clang_analyzer_container_end(const Container&);
13 
14 void clang_analyzer_denote(long, const char*);
15 void clang_analyzer_express(long);
16 void clang_analyzer_eval(bool);
17 void clang_analyzer_warnIfReached();
18 
begin(const std::vector<int> & V)19 void begin(const std::vector<int> &V) {
20   V.begin();
21 
22   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
23   clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
24                                                              // expected-note@-1{{$V.begin()}}
25 }
26 
end(const std::vector<int> & V)27 void end(const std::vector<int> &V) {
28   V.end();
29 
30   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
31   clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end()}}
32                                                            // expected-note@-1{{$V.end()}}
33 }
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 ///
37 /// C O N T A I N E R   A S S I G N M E N T S
38 ///
39 ////////////////////////////////////////////////////////////////////////////////
40 
41 // Move
42 
move_assignment(std::vector<int> & V1,std::vector<int> & V2)43 void move_assignment(std::vector<int> &V1, std::vector<int> &V2) {
44   V1.cbegin();
45   V1.cend();
46   V2.cbegin();
47   V2.cend();
48   long B1 = clang_analyzer_container_begin(V1);
49   long E1 = clang_analyzer_container_end(V1);
50   long B2 = clang_analyzer_container_begin(V2);
51   long E2 = clang_analyzer_container_end(V2);
52   V1 = std::move(V2);
53   clang_analyzer_eval(clang_analyzer_container_begin(V1) == B2); // expected-warning{{TRUE}}
54                                                                  // expected-note@-1{{TRUE}}
55   clang_analyzer_eval(clang_analyzer_container_end(V2) == E2); // expected-warning{{TRUE}}
56                                                                // expected-note@-1{{TRUE}}
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 ///
61 /// C O N T A I N E R   M O D I F I E R S
62 ///
63 ////////////////////////////////////////////////////////////////////////////////
64 
65 /// push_back()
66 ///
67 /// Design decision: extends containers to the ->BACK-> (i.e. the
68 /// past-the-end position of the container is incremented).
69 
70 void clang_analyzer_dump(void*);
71 
push_back(std::vector<int> & V,int n)72 void push_back(std::vector<int> &V, int n) {
73   V.cbegin();
74   V.cend();
75 
76   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
77   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
78 
79   V.push_back(n); // expected-note 2{{Container 'V' extended to the back by 1 position}}
80 
81   clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
82                                                              // expected-note@-1{{$V.begin()}}
83   clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
84                                                            // expected-note@-1{{$V.end() + 1}}
85 }
86 
87 /// emplace_back()
88 ///
89 /// Design decision: extends containers to the ->BACK-> (i.e. the
90 /// past-the-end position of the container is incremented).
91 
emplace_back(std::vector<int> & V,int n)92 void emplace_back(std::vector<int> &V, int n) {
93   V.cbegin();
94   V.cend();
95 
96   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
97   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
98 
99   V.emplace_back(n); // expected-note 2{{Container 'V' extended to the back by 1 position}}
100 
101   clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
102                                                              // expected-note@-1{{$V.begin()}}
103   clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
104                                                            // expected-note@-1{{$V.end() + 1}}
105 }
106 
107 /// pop_back()
108 ///
109 /// Design decision: shrinks containers to the <-FRONT<- (i.e. the
110 /// past-the-end position of the container is decremented).
111 
pop_back(std::vector<int> & V,int n)112 void pop_back(std::vector<int> &V, int n) {
113   V.cbegin();
114   V.cend();
115 
116   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
117   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
118 
119   V.pop_back(); // expected-note 2{{Container 'V' shrank from the back by 1 position}}
120 
121 
122   clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
123                                                              // expected-note@-1{{$V.begin()}}
124   clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() - 1}}
125                                                            // expected-note@-1{{$V.end() - 1}}
126 }
127 
128 /// push_front()
129 ///
130 /// Design decision: extends containers to the <-FRONT<- (i.e. the first
131 /// position of the container is decremented).
132 
push_front(std::list<int> & L,int n)133 void push_front(std::list<int> &L, int n) {
134   L.cbegin();
135   L.cend();
136 
137   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
138   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
139 
140   L.push_front(n); // expected-note 2{{Container 'L' extended to the front by 1 position}}
141 
142   clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() - 1}}
143                                                              // expected-note@-1{{$L.begin() - 1}}
144   clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
145                                                            // expected-note@-1{{$L.end()}}
146 }
147 
148 /// emplace_front()
149 ///
150 /// Design decision: extends containers to the <-FRONT<- (i.e. the first
151 /// position of the container is decremented).
152 
emplace_front(std::list<int> & L,int n)153 void emplace_front(std::list<int> &L, int n) {
154   L.cbegin();
155   L.cend();
156 
157   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
158   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
159 
160   L.emplace_front(n); // expected-note 2{{Container 'L' extended to the front by 1 position}}
161 
162   clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() - 1}}
163                                                              // expected-note@-1{{$L.begin() - 1}}
164   clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
165                                                            // expected-note@-1{{$L.end()}}
166 }
167 
168 /// pop_front()
169 ///
170 /// Design decision: shrinks containers to the ->BACK-> (i.e. the first
171 /// position of the container is incremented).
172 
pop_front(std::list<int> & L,int n)173 void pop_front(std::list<int> &L, int n) {
174   L.cbegin();
175   L.cend();
176 
177   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
178   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
179 
180   L.pop_front(); // expected-note 2{{Container 'L' shrank from the front by 1 position}}
181 
182   clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() + 1}}
183                                                              // expected-note@-1{{$L.begin() + 1}}
184   clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
185                                                            // expected-note@-1{{$L.end()}}
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 ///
190 /// O T H E R   T E S T S
191 ///
192 ////////////////////////////////////////////////////////////////////////////////
193 
194 /// Track local variable
195 
push_back()196 void push_back() {
197   std::vector<int> V;
198   V.end();
199 
200   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
201 
202   V.push_back(1); // expected-note{{Container 'V' extended to the back by 1 position}}
203 
204   clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
205                                                            // expected-note@-1{{$V.end() + 1}}
206 }
207 
208 /// Track the right container only
209 
push_back1(std::vector<int> & V1,std::vector<int> & V2,int n)210 void push_back1(std::vector<int> &V1, std::vector<int> &V2, int n) {
211   V1.cbegin();
212   V1.cend();
213   V2.cbegin();
214   V2.cend();
215 
216   clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
217 
218   V2.push_back(n); // no-note
219 
220   clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
221                                                               // expected-note@-1{{$V1.begin()}}
222 }
223 
push_back2(std::vector<int> & V1,std::vector<int> & V2,int n)224 void push_back2(std::vector<int> &V1, std::vector<int> &V2, int n) {
225   V1.cbegin();
226   V1.cend();
227   V2.cbegin();
228   V2.cend();
229 
230   clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
231   clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
232 
233   V1.push_back(n); // expected-note{{Container 'V1' extended to the back by 1 position}}
234                    // Only once!
235 
236   clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
237                                                               // expected-note@-1{{$V1.begin()}}
238 
239   clang_analyzer_express(clang_analyzer_container_begin(V2)); // expected-warning{{$V2.begin()}}
240                                                               // expected-note@-1{{$V2.begin()}}
241 }
242 
243 /// Print Container Data as Part of the Program State
244 
245 void clang_analyzer_printState();
246 
print_state(std::vector<int> & V)247 void print_state(std::vector<int> &V) {
248   V.cbegin();
249   clang_analyzer_printState();
250 
251 // CHECK:      "checker_messages": [
252 // CHECK-NEXT:   { "checker": "alpha.cplusplus.ContainerModeling", "messages": [
253 // CHECK-NEXT:     "Container Data :",
254 // CHECK-NEXT:     "SymRegion{reg_$[[#]]<std::vector<int> & V>} : [ conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} .. <Unknown> ]"
255 // CHECK-NEXT:   ]}
256 
257   V.cend();
258   clang_analyzer_printState();
259 
260 // CHECK:      "checker_messages": [
261 // CHECK-NEXT:   { "checker": "alpha.cplusplus.ContainerModeling", "messages": [
262 // CHECK-NEXT:     "Container Data :",
263 // CHECK-NEXT:     "SymRegion{reg_$[[#]]<std::vector<int> & V>} : [ conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} .. conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} ]"
264 // CHECK-NEXT:   ]}
265 }
266