Browse Source

Merge #7888: prevector: fix 2 bugs in currently unreached code paths

a7af72a prevector::swap: fix (unreached) data corruption (Kaz Wesley)
4ed41a2 test prevector::swap (Kaz Wesley)
1e2c29f prevector: destroy elements only via erase() (Kaz Wesley)
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
ec870e1399
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 19
      src/prevector.h
  2. 15
      src/test/prevector_tests.cpp

19
src/prevector.h

@ -298,9 +298,8 @@ public:
} }
void resize(size_type new_size) { void resize(size_type new_size) {
while (size() > new_size) { if (size() > new_size) {
item_ptr(size() - 1)->~T(); erase(item_ptr(new_size), end());
_size--;
} }
if (new_size > capacity()) { if (new_size > capacity()) {
change_capacity(new_size); change_capacity(new_size);
@ -368,10 +367,7 @@ public:
} }
iterator erase(iterator pos) { iterator erase(iterator pos) {
(*pos).~T(); return erase(pos, pos + 1);
memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos))));
_size--;
return pos;
} }
iterator erase(iterator first, iterator last) { iterator erase(iterator first, iterator last) {
@ -396,7 +392,7 @@ public:
} }
void pop_back() { void pop_back() {
_size--; erase(end() - 1, end());
} }
T& front() { T& front() {
@ -416,12 +412,7 @@ public:
} }
void swap(prevector<N, T, Size, Diff>& other) { void swap(prevector<N, T, Size, Diff>& other) {
if (_size & other._size & 1) { std::swap(_union, other._union);
std::swap(_union.capacity, other._union.capacity);
std::swap(_union.indirect, other._union.indirect);
} else {
std::swap(_union, other._union);
}
std::swap(_size, other._size); std::swap(_size, other._size);
} }

15
src/test/prevector_tests.cpp

@ -19,9 +19,11 @@ template<unsigned int N, typename T>
class prevector_tester { class prevector_tester {
typedef std::vector<T> realtype; typedef std::vector<T> realtype;
realtype real_vector; realtype real_vector;
realtype real_vector_alt;
typedef prevector<N, T> pretype; typedef prevector<N, T> pretype;
pretype pre_vector; pretype pre_vector;
pretype pre_vector_alt;
typedef typename pretype::size_type Size; typedef typename pretype::size_type Size;
@ -149,6 +151,12 @@ public:
pre_vector.shrink_to_fit(); pre_vector.shrink_to_fit();
test(); test();
} }
void swap() {
real_vector.swap(real_vector_alt);
pre_vector.swap(pre_vector_alt);
test();
}
}; };
BOOST_AUTO_TEST_CASE(PrevectorTestInt) BOOST_AUTO_TEST_CASE(PrevectorTestInt)
@ -204,12 +212,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt)
if (test.size() > 0) { if (test.size() > 0) {
test.update(insecure_rand() % test.size(), insecure_rand()); test.update(insecure_rand() % test.size(), insecure_rand());
} }
if (((r >> 11) & 1024) == 11) { if (((r >> 11) % 1024) == 11) {
test.clear(); test.clear();
} }
if (((r >> 21) & 512) == 12) { if (((r >> 21) % 512) == 12) {
test.assign(insecure_rand() % 32, insecure_rand()); test.assign(insecure_rand() % 32, insecure_rand());
} }
if (((r >> 15) % 64) == 3) {
test.swap();
}
} }
} }
} }

Loading…
Cancel
Save