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 -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 -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 } 25 26 void end(const std::vector<int> &V) { 27 V.end(); 28 29 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 30 clang_analyzer_express(clang_analyzer_container_end(V)); //expected-warning{{$V.end()}} 31 } 32 33 //////////////////////////////////////////////////////////////////////////////// 34 /// 35 /// C O N T A I N E R A S S I G N M E N T S 36 /// 37 //////////////////////////////////////////////////////////////////////////////// 38 39 // Move 40 41 void move_assignment(std::vector<int> &V1, std::vector<int> &V2) { 42 V1.cbegin(); 43 V1.cend(); 44 V2.cbegin(); 45 V2.cend(); 46 long B1 = clang_analyzer_container_begin(V1); 47 long E1 = clang_analyzer_container_end(V1); 48 long B2 = clang_analyzer_container_begin(V2); 49 long E2 = clang_analyzer_container_end(V2); 50 V1 = std::move(V2); 51 clang_analyzer_eval(clang_analyzer_container_begin(V1) == B2); //expected-warning{{TRUE}} 52 clang_analyzer_eval(clang_analyzer_container_end(V2) == E2); //expected-warning{{TRUE}} 53 } 54 55 //////////////////////////////////////////////////////////////////////////////// 56 /// 57 /// C O N T A I N E R M O D I F I E R S 58 /// 59 //////////////////////////////////////////////////////////////////////////////// 60 61 /// push_back() 62 /// 63 /// Design decision: extends containers to the ->RIGHT-> (i.e. the 64 /// past-the-end position of the container is incremented). 65 66 void push_back(std::vector<int> &V, int n) { 67 V.cbegin(); 68 V.cend(); 69 70 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 71 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 72 73 V.push_back(n); 74 75 clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} 76 clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}} 77 } 78 79 /// emplace_back() 80 /// 81 /// Design decision: extends containers to the ->RIGHT-> (i.e. the 82 /// past-the-end position of the container is incremented). 83 84 void emplace_back(std::vector<int> &V, int n) { 85 V.cbegin(); 86 V.cend(); 87 88 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 89 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 90 91 V.emplace_back(n); 92 93 clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} 94 clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}} 95 } 96 97 /// pop_back() 98 /// 99 /// Design decision: shrinks containers to the <-LEFT<- (i.e. the 100 /// past-the-end position of the container is decremented). 101 102 void pop_back(std::vector<int> &V, int n) { 103 V.cbegin(); 104 V.cend(); 105 106 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 107 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 108 109 V.pop_back(); 110 111 clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} 112 clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() - 1}} 113 } 114 115 /// push_front() 116 /// 117 /// Design decision: extends containers to the <-LEFT<- (i.e. the first 118 /// position of the container is decremented). 119 120 void push_front(std::deque<int> &D, int n) { 121 D.cbegin(); 122 D.cend(); 123 124 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 125 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 126 127 D.push_front(n); 128 129 clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() - 1 (to correctly track the container's size) 130 clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}} 131 } 132 133 /// emplace_front() 134 /// 135 /// Design decision: extends containers to the <-LEFT<- (i.e. the first 136 /// position of the container is decremented). 137 138 void deque_emplace_front(std::deque<int> &D, int n) { 139 D.cbegin(); 140 D.cend(); 141 142 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 143 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 144 145 D.emplace_front(n); 146 147 clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin - 1 (to correctly track the container's size) 148 clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}} 149 } 150 151 /// pop_front() 152 /// 153 /// Design decision: shrinks containers to the ->RIGHT-> (i.e. the first 154 /// position of the container is incremented). 155 156 void deque_pop_front(std::deque<int> &D, int n) { 157 D.cbegin(); 158 D.cend(); 159 160 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 161 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 162 163 D.pop_front(); 164 165 clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin() + 1}} 166 clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}} 167 } 168 169 void clang_analyzer_printState(); 170 171 void print_state(std::vector<int> &V) { 172 V.cbegin(); 173 clang_analyzer_printState(); 174 175 // CHECK: "checker_messages": [ 176 // CHECK-NEXT: { "checker": "alpha.cplusplus.ContainerModeling", "messages": [ 177 // CHECK-NEXT: "Container Data :", 178 // CHECK-NEXT: "SymRegion{reg_$[[#]]<std::vector<int> & V>} : [ conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} .. <Unknown> ]" 179 // CHECK-NEXT: ]} 180 181 V.cend(); 182 clang_analyzer_printState(); 183 184 // CHECK: "checker_messages": [ 185 // CHECK-NEXT: { "checker": "alpha.cplusplus.ContainerModeling", "messages": [ 186 // CHECK-NEXT: "Container Data :", 187 // CHECK-NEXT: "SymRegion{reg_$[[#]]<std::vector<int> & V>} : [ conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} .. conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]} ]" 188 // CHECK-NEXT: ]} 189 } 190