Skip to content

Commit ec870e1

Browse files
committed
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)
2 parents 73fc922 + a7af72a commit ec870e1

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

src/prevector.h

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,8 @@ class prevector {
298298
}
299299

300300
void resize(size_type new_size) {
301-
while (size() > new_size) {
302-
item_ptr(size() - 1)->~T();
303-
_size--;
301+
if (size() > new_size) {
302+
erase(item_ptr(new_size), end());
304303
}
305304
if (new_size > capacity()) {
306305
change_capacity(new_size);
@@ -368,10 +367,7 @@ class prevector {
368367
}
369368

370369
iterator erase(iterator pos) {
371-
(*pos).~T();
372-
memmove(&(*pos), &(*pos) + 1, ((char*)&(*end())) - ((char*)(1 + &(*pos))));
373-
_size--;
374-
return pos;
370+
return erase(pos, pos + 1);
375371
}
376372

377373
iterator erase(iterator first, iterator last) {
@@ -396,7 +392,7 @@ class prevector {
396392
}
397393

398394
void pop_back() {
399-
_size--;
395+
erase(end() - 1, end());
400396
}
401397

402398
T& front() {
@@ -416,12 +412,7 @@ class prevector {
416412
}
417413

418414
void swap(prevector<N, T, Size, Diff>& other) {
419-
if (_size & other._size & 1) {
420-
std::swap(_union.capacity, other._union.capacity);
421-
std::swap(_union.indirect, other._union.indirect);
422-
} else {
423-
std::swap(_union, other._union);
424-
}
415+
std::swap(_union, other._union);
425416
std::swap(_size, other._size);
426417
}
427418

src/test/prevector_tests.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ template<unsigned int N, typename T>
1919
class prevector_tester {
2020
typedef std::vector<T> realtype;
2121
realtype real_vector;
22+
realtype real_vector_alt;
2223

2324
typedef prevector<N, T> pretype;
2425
pretype pre_vector;
26+
pretype pre_vector_alt;
2527

2628
typedef typename pretype::size_type Size;
2729

@@ -149,6 +151,12 @@ class prevector_tester {
149151
pre_vector.shrink_to_fit();
150152
test();
151153
}
154+
155+
void swap() {
156+
real_vector.swap(real_vector_alt);
157+
pre_vector.swap(pre_vector_alt);
158+
test();
159+
}
152160
};
153161

154162
BOOST_AUTO_TEST_CASE(PrevectorTestInt)
@@ -204,12 +212,15 @@ BOOST_AUTO_TEST_CASE(PrevectorTestInt)
204212
if (test.size() > 0) {
205213
test.update(insecure_rand() % test.size(), insecure_rand());
206214
}
207-
if (((r >> 11) & 1024) == 11) {
215+
if (((r >> 11) % 1024) == 11) {
208216
test.clear();
209217
}
210-
if (((r >> 21) & 512) == 12) {
218+
if (((r >> 21) % 512) == 12) {
211219
test.assign(insecure_rand() % 32, insecure_rand());
212220
}
221+
if (((r >> 15) % 64) == 3) {
222+
test.swap();
223+
}
213224
}
214225
}
215226
}

0 commit comments

Comments
 (0)