1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.MismatchedIterator -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.MismatchedIterator -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 good_insert1(std::vector<int> &v, int n) { 7 v.insert(v.cbegin(), n); // no-warning 8 } 9 10 11 void good_insert2(std::vector<int> &v, int len, int n) { 12 v.insert(v.cbegin(), len, n); // no-warning 13 } 14 15 void good_insert3(std::vector<int> &v1, std::vector<int> &v2) { 16 v1.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // no-warning 17 } 18 19 void good_insert4(std::vector<int> &v, int len, int n) { 20 v.insert(v.cbegin(), {n-1, n, n+1}); // no-warning 21 } 22 23 void good_insert_find(std::vector<int> &v, int n, int m) { 24 auto i = std::find(v.cbegin(), v.cend(), n); 25 v.insert(i, m); // no-warning 26 } 27 28 void good_erase1(std::vector<int> &v) { 29 v.erase(v.cbegin()); // no-warning 30 } 31 32 void good_erase2(std::vector<int> &v) { 33 v.erase(v.cbegin(), v.cend()); // no-warning 34 } 35 36 void good_emplace(std::vector<int> &v, int n) { 37 v.emplace(v.cbegin(), n); // no-warning 38 } 39 40 void good_ctor(std::vector<int> &v) { 41 std::vector<int> new_v(v.cbegin(), v.cend()); // no-warning 42 } 43 44 void good_find(std::vector<int> &v, int n) { 45 std::find(v.cbegin(), v.cend(), n); // no-warning 46 } 47 48 void good_find_first_of(std::vector<int> &v1, std::vector<int> &v2) { 49 std::find_first_of(v1.cbegin(), v1.cend(), v2.cbegin(), v2.cend()); // no-warning 50 } 51 52 void good_copy(std::vector<int> &v1, std::vector<int> &v2, int n) { 53 std::copy(v1.cbegin(), v1.cend(), v2.begin()); // no-warning 54 } 55 56 void good_move_find1(std::vector<int> &v1, std::vector<int> &v2, int n) { 57 auto i0 = v2.cbegin(); 58 v1 = std::move(v2); 59 std::find(i0, v1.cend(), n); // no-warning 60 } 61 62 void bad_insert1(std::vector<int> &v1, std::vector<int> &v2, int n) { 63 v2.insert(v1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}} 64 } 65 66 void bad_insert2(std::vector<int> &v1, std::vector<int> &v2, int len, int n) { 67 v2.insert(v1.cbegin(), len, n); // expected-warning{{Container accessed using foreign iterator argument}} 68 } 69 70 void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) { 71 v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // expected-warning{{Container accessed using foreign iterator argument}} 72 v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} 73 v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} 74 } 75 76 void bad_insert4(std::vector<int> &v1, std::vector<int> &v2, int len, int n) { 77 v2.insert(v1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}} 78 } 79 80 void bad_erase1(std::vector<int> &v1, std::vector<int> &v2) { 81 v2.erase(v1.cbegin()); // expected-warning{{Container accessed using foreign iterator argument}} 82 } 83 84 void bad_erase2(std::vector<int> &v1, std::vector<int> &v2) { 85 v2.erase(v2.cbegin(), v1.cend()); // expected-warning{{Container accessed using foreign iterator argument}} 86 v2.erase(v1.cbegin(), v2.cend()); // expected-warning{{Container accessed using foreign iterator argument}} 87 v2.erase(v1.cbegin(), v1.cend()); // expected-warning{{Container accessed using foreign iterator argument}} 88 } 89 90 void bad_emplace(std::vector<int> &v1, std::vector<int> &v2, int n) { 91 v2.emplace(v1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}} 92 } 93 94 void good_move_find2(std::vector<int> &v1, std::vector<int> &v2, int n) { 95 auto i0 = --v2.cend(); 96 v1 = std::move(v2); 97 std::find(i0, v1.cend(), n); // no-warning 98 } 99 100 void good_move_find3(std::vector<int> &v1, std::vector<int> &v2, int n) { 101 auto i0 = v2.cend(); 102 v1 = std::move(v2); 103 v2.push_back(n); 104 std::find(v2.cbegin(), i0, n); // no-warning 105 } 106 107 void good_comparison(std::vector<int> &v) { 108 if (v.cbegin() == v.cend()) {} // no-warning 109 } 110 111 void bad_ctor(std::vector<int> &v1, std::vector<int> &v2) { 112 std::vector<int> new_v(v1.cbegin(), v2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} 113 } 114 115 void bad_find(std::vector<int> &v1, std::vector<int> &v2, int n) { 116 std::find(v1.cbegin(), v2.cend(), n); // expected-warning{{Iterators of different containers used where the same container is expected}} 117 } 118 119 void bad_find_first_of(std::vector<int> &v1, std::vector<int> &v2) { 120 std::find_first_of(v1.cbegin(), v2.cend(), v2.cbegin(), v2.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} 121 std::find_first_of(v1.cbegin(), v1.cend(), v2.cbegin(), v1.cend()); // expected-warning{{Iterators of different containers used where the same container is expected}} 122 } 123 124 void bad_move_find1(std::vector<int> &v1, std::vector<int> &v2, int n) { 125 auto i0 = v2.cbegin(); 126 v1 = std::move(v2); 127 std::find(i0, v2.cend(), n); // expected-warning{{Iterators of different containers used where the same container is expected}} 128 } 129 130 void bad_insert_find(std::vector<int> &v1, std::vector<int> &v2, int n, int m) { 131 auto i = std::find(v1.cbegin(), v1.cend(), n); 132 v2.insert(i, m); // expected-warning{{Container accessed using foreign iterator argument}} 133 } 134 135 void good_overwrite(std::vector<int> &v1, std::vector<int> &v2, int n) { 136 auto i = v1.cbegin(); 137 i = v2.cbegin(); 138 v2.insert(i, n); // no-warning 139 } 140 141 void bad_overwrite(std::vector<int> &v1, std::vector<int> &v2, int n) { 142 auto i = v1.cbegin(); 143 i = v2.cbegin(); 144 v1.insert(i, n); // expected-warning{{Container accessed using foreign iterator argument}} 145 } 146 147 void good_move(std::vector<int> &v1, std::vector<int> &v2) { 148 const auto i0 = ++v2.cbegin(); 149 v1 = std::move(v2); 150 v1.erase(i0); // no-warning 151 } 152 153 void bad_move(std::vector<int> &v1, std::vector<int> &v2) { 154 const auto i0 = ++v2.cbegin(); 155 v1 = std::move(v2); 156 v2.erase(i0); // expected-warning{{Container accessed using foreign iterator argument}} 157 } 158 159 void bad_move_find2(std::vector<int> &v1, std::vector<int> &v2, int n) { 160 auto i0 = --v2.cend(); 161 v1 = std::move(v2); 162 std::find(i0, v2.cend(), n); // expected-warning{{Iterators of different containers used where the same container is expected}} 163 } 164 165 void bad_move_find3(std::vector<int> &v1, std::vector<int> &v2, int n) { 166 auto i0 = v2.cend(); 167 v1 = std::move(v2); 168 std::find(v1.cbegin(), i0, n); // expected-warning{{Iterators of different containers used where the same container is expected}} 169 } 170 171 void bad_comparison(std::vector<int> &v1, std::vector<int> &v2) { 172 if (v1.cbegin() != v2.cend()) { // expected-warning{{Iterators of different containers used where the same container is expected}} 173 *v1.cbegin(); 174 } 175 } 176