diff options
| author | Wladimir J. van der Laan <[email protected]> | 2016-04-18 12:41:57 +0200 |
|---|---|---|
| committer | Wladimir J. van der Laan <[email protected]> | 2016-04-18 12:42:14 +0200 |
| commit | ec870e13991fa5f143308485dda0272eef9f0a3f (patch) | |
| tree | 086ebada01f780d23b4785212b50bad679ddb1af /src | |
| parent | Merge #7603: Build System: Use PACKAGE_TARNAME in NSIS script (diff) | |
| parent | prevector::swap: fix (unreached) data corruption (diff) | |
| download | discoin-ec870e13991fa5f143308485dda0272eef9f0a3f.tar.xz discoin-ec870e13991fa5f143308485dda0272eef9f0a3f.zip | |
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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/prevector.h | 19 | ||||
| -rw-r--r-- | src/test/prevector_tests.cpp | 15 |
2 files changed, 18 insertions, 16 deletions
diff --git a/src/prevector.h b/src/prevector.h index 1da459bcf..a0e1e140b 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 01a45b540..b39b90353 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(); + } } } } |