From 3495af3f697b552eed2f622ad18bf1a8447d6b09 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 4 Sep 2017 17:41:34 +0100 Subject: [PATCH] PR libstdc++/81891 fix double-free in hashtable constructor Backport from mainline 2017-08-18 Jonathan Wakely PR libstdc++/81891 * include/bits/hashtable.h (_Hashtable(_InputIterator, _InputIterator, size_type, const _H1&, const _H2&, const _Hash&, const _Equal&, const _ExtractKey&, const allocator_type&)): Let destructor do clean up if an exception is thrown. * testsuite/23_containers/unordered_map/cons/81891.cc: New. From-SVN: r251671 --- libstdc++-v3/ChangeLog | 10 +++ libstdc++-v3/include/bits/hashtable.h | 13 +--- .../23_containers/unordered_map/cons/81891.cc | 68 +++++++++++++++++++ 3 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_map/cons/81891.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ec50f013ad6f..d876052b2a86 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2017-09-04 Jonathan Wakely + Backport from mainline + 2017-08-18 Jonathan Wakely + + PR libstdc++/81891 + * include/bits/hashtable.h (_Hashtable(_InputIterator, _InputIterator, + size_type, const _H1&, const _H2&, const _Hash&, const _Equal&, + const _ExtractKey&, const allocator_type&)): Let destructor do clean + up if an exception is thrown. + * testsuite/23_containers/unordered_map/cons/81891.cc: New. + Backport from mainline 2017-07-31 Marek Polacek diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index f5f298ea33c2..332db5cdf49f 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -834,17 +834,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_bucket_count = __bkt_count; } - __try - { - for (; __f != __l; ++__f) - this->insert(*__f); - } - __catch(...) - { - clear(); - _M_deallocate_buckets(); - __throw_exception_again; - } + for (; __f != __l; ++__f) + this->insert(*__f); } template. + +// { dg-options "-std=gnu++11" } + +#include +#include +#include + +struct fails_on_copy { + fails_on_copy() = default; + fails_on_copy(const fails_on_copy&) { throw 0; }; +}; + +using value_type = std::pair; + +void +test01() +{ + value_type p; + try + { + std::unordered_map umap(&p, &p + 1); + } + catch(...) + { } +} + +void +test02() +{ + using Alloc = __gnu_test::tracker_allocator; + using std::hash; + using std::equal_to; + + value_type p; + try + { + std::unordered_map, equal_to, Alloc> + umap(&p, &p + 1); + } + catch(...) + { } + + using counter = __gnu_test::tracker_allocator_counter; + VERIFY(counter::get_allocation_count() == counter::get_deallocation_count()); +} + +int +main() +{ + test01(); + test02(); +} -- 2.47.2