Fix exception bug in asssignment.

The hash and key equality functions were assigned before allocating new
buckets. If that allocation failed, then the existing elements would be
left in place - so if accessed after the exception they could be in the
wrong buckets or equivalent elements could be incorrectly grouped
together.
This commit is contained in:
Daniel James
2016-10-02 13:04:25 +01:00
parent 588ad6e69f
commit e7b20d2877
5 changed files with 159 additions and 6 deletions

View File

@@ -584,7 +584,6 @@ namespace boost { namespace unordered { namespace detail {
{
// Strong exception safety.
set_hash_functions new_func_this(*this, x);
new_func_this.commit();
mlf_ = x.mlf_;
recalculate_max_load();
@@ -597,6 +596,7 @@ namespace boost { namespace unordered { namespace detail {
clear_buckets();
}
new_func_this.commit();
static_cast<table_impl*>(this)->assign_buckets(x);
}
@@ -663,11 +663,13 @@ namespace boost { namespace unordered { namespace detail {
}
else {
set_hash_functions new_func_this(*this, x);
new_func_this.commit();
mlf_ = x.mlf_;
recalculate_max_load();
if (!size_ && !x.size_) return;
if (!size_ && !x.size_) {
new_func_this.commit();
return;
}
if (x.size_ >= max_load_) {
create_buckets(min_buckets_for_size(x.size_));
@@ -676,6 +678,7 @@ namespace boost { namespace unordered { namespace detail {
clear_buckets();
}
new_func_this.commit();
static_cast<table_impl*>(this)->move_assign_buckets(x);
}
}