Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / container-modeling.cpp
blobbf4a12a0e0fe298d44616c6fda4b15bcc608088c
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
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
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
7 #include "Inputs/system-header-simulator-cxx.h"
9 template <typename Container>
10 long clang_analyzer_container_begin(const Container&);
11 template <typename Container>
12 long clang_analyzer_container_end(const Container&);
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();
19 void begin(const std::vector<int> &V) {
20 V.begin();
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()}}
27 void end(const std::vector<int> &V) {
28 V.end();
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()}}
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 ////////////////////////////////////////////////////////////////////////////////
41 // Move
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}}
59 ////////////////////////////////////////////////////////////////////////////////
60 ///
61 /// C O N T A I N E R M O D I F I E R S
62 ///
63 ////////////////////////////////////////////////////////////////////////////////
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).
70 void clang_analyzer_dump(void*);
72 void push_back(std::vector<int> &V, int n) {
73 V.cbegin();
74 V.cend();
76 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
77 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
79 V.push_back(n); // expected-note 2{{Container 'V' extended to the back by 1 position}}
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}}
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).
92 void emplace_back(std::vector<int> &V, int n) {
93 V.cbegin();
94 V.cend();
96 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
97 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
99 V.emplace_back(n); // expected-note 2{{Container 'V' extended to the back by 1 position}}
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}}
107 /// pop_back()
109 /// Design decision: shrinks containers to the <-FRONT<- (i.e. the
110 /// past-the-end position of the container is decremented).
112 void pop_back(std::vector<int> &V, int n) {
113 V.cbegin();
114 V.cend();
116 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
117 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
119 V.pop_back(); // expected-note 2{{Container 'V' shrank from the back by 1 position}}
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}}
128 /// push_front()
130 /// Design decision: extends containers to the <-FRONT<- (i.e. the first
131 /// position of the container is decremented).
133 void push_front(std::list<int> &L, int n) {
134 L.cbegin();
135 L.cend();
137 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
138 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
140 L.push_front(n); // expected-note 2{{Container 'L' extended to the front by 1 position}}
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()}}
148 /// emplace_front()
150 /// Design decision: extends containers to the <-FRONT<- (i.e. the first
151 /// position of the container is decremented).
153 void emplace_front(std::list<int> &L, int n) {
154 L.cbegin();
155 L.cend();
157 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
158 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
160 L.emplace_front(n); // expected-note 2{{Container 'L' extended to the front by 1 position}}
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()}}
168 /// pop_front()
170 /// Design decision: shrinks containers to the ->BACK-> (i.e. the first
171 /// position of the container is incremented).
173 void pop_front(std::list<int> &L, int n) {
174 L.cbegin();
175 L.cend();
177 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
178 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
180 L.pop_front(); // expected-note 2{{Container 'L' shrank from the front by 1 position}}
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()}}
188 ////////////////////////////////////////////////////////////////////////////////
190 /// O T H E R T E S T S
192 ////////////////////////////////////////////////////////////////////////////////
194 /// Track local variable
196 void push_back() {
197 std::vector<int> V;
198 V.end();
200 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
202 V.push_back(1); // expected-note{{Container 'V' extended to the back by 1 position}}
204 clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
205 // expected-note@-1{{$V.end() + 1}}
208 /// Track the right container only
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();
216 clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
218 V2.push_back(n); // no-note
220 clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
221 // expected-note@-1{{$V1.begin()}}
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();
230 clang_analyzer_denote(clang_analyzer_container_begin(V1), "$V1.begin()");
231 clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
233 V1.push_back(n); // expected-note{{Container 'V1' extended to the back by 1 position}}
234 // Only once!
236 clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V1.begin()}}
237 // expected-note@-1{{$V1.begin()}}
239 clang_analyzer_express(clang_analyzer_container_begin(V2)); // expected-warning{{$V2.begin()}}
240 // expected-note@-1{{$V2.begin()}}
243 /// Print Container Data as Part of the Program State
245 void clang_analyzer_printState();
247 void print_state(std::vector<int> &V) {
248 V.cbegin();
249 clang_analyzer_printState();
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: ]}
257 V.cend();
258 clang_analyzer_printState();
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: ]}