aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-04-18 12:41:57 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-04-18 12:42:14 +0200
commitec870e13991fa5f143308485dda0272eef9f0a3f (patch)
tree086ebada01f780d23b4785212b50bad679ddb1af
parent73fc922ed64333d45f18d8a448f30cfa2ae0281e (diff)
parenta7af72a697a8decab364792230153f114be3919c (diff)
downloadbitcoin-ec870e13991fa5f143308485dda0272eef9f0a3f.tar.xz
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)
-rw-r--r--src/prevector.h19
-rw-r--r--src/test/prevector_tests.cpp15
2 files changed, 18 insertions, 16 deletions
diff --git a/src/prevector.h b/src/prevector.h
index 1da459bcfe..a0e1e140b4 100644
--- a/src/prevector.h
+++ b/src/prevector.h
@@ -298,9 +298,8 @@ public:
}
void resize(size_type new_size) {
- while (size() > new_size) {
- item_ptr(size() - 1)->~T();
- _size--;
+ if (size() > new_size) {
+ erase(item_ptr(new_size), end());
}
if (new_size > capacity()) {
change_capacity(new_size);
@@ -368,10 +367,7 @@ public:
}
iterator erase(iterator pos) {
- (*pos).~T();
- memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos))));
- _size--;
- return pos;
+ return erase(pos, pos + 1);
}
iterator erase(iterator first, iterator last) {
@@ -396,7 +392,7 @@ public:
}
void pop_back() {
- _size--;
+ erase(end() - 1, end());
}
T& front() {
@@ -416,12 +412,7 @@ public:
}
void swap(prevector<N, T, Size, Diff>& other) {
- if (_size & other._size & 1) {
- std::swap(_union.capacity, other._union.capacity);
- std::swap(_union.indirect, other._union.indirect);
- } else {
- std::swap(_union, other._union);
- }
+ std::swap(_union, other._union);
std::swap(_size, other._size);
}
diff --git a/src/test/prevector_tests.cpp b/src/test/prevector_tests.cpp
index 01a45b540d..b39b903530 100644
--- a/src/test/prevector_tests.cpp
+++ b/src/test/prevector_tests.cpp
@@ -19,9 +19,11 @@ template<unsigned int N, typename T>
class prevector_tester {
typedef std::vector<T> realtype;
realtype real_vector;
+ realtype real_vector_alt;
typedef prevector<N, T> pretype;
pretype pre_vector;
+ pretype pre_vector_alt;
typedef typename pretype::size_type Size;
@@ -149,6 +151,12 @@ public:
pre_vector.shrink_to_fit();
test();
}
+
+ void swap() {
+ real_vector.swap(real_vector_alt);
+ pre_vector.swap(pre_vector_alt);
+ test();
+ }
};
BOOST_AUTO_TEST_CASE(PrevectorTestInt)
@@ -204,12 +212,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt)
if (test.size() > 0) {
test.update(insecure_rand() % test.size(), insecure_rand());
}
- if (((r >> 11) & 1024) == 11) {
+ if (((r >> 11) % 1024) == 11) {
test.clear();
}
- if (((r >> 21) & 512) == 12) {
+ if (((r >> 21) % 512) == 12) {
test.assign(insecure_rand() % 32, insecure_rand());
}
+ if (((r >> 15) % 64) == 3) {
+ test.swap();
+ }
}
}
}