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 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 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 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 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 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 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 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 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 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 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 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 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 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