diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-01-19 11:46:31 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-01-19 11:46:31 +0100 |
commit | ac1384b7c5d9ac762c41f0b1e350aaf1f5fe3170 (patch) | |
tree | 1338823bdcd2c9cae56ffc7b00f9e2e3dd581dad | |
parent | e9c9f128d7192b21c4be77422d76494aa7ddb474 (diff) | |
download | gcc-ac1384b7c5d9ac762c41f0b1e350aaf1f5fe3170.zip gcc-ac1384b7c5d9ac762c41f0b1e350aaf1f5fe3170.tar.gz gcc-ac1384b7c5d9ac762c41f0b1e350aaf1f5fe3170.tar.bz2 |
re PR libstdc++/51845 (23_containers/unordered_multimap/erase/24061-multimap.cc segfault)
PR libstdc++/51845
* include/bits/hashtable.h
(_Hashtable<>::erase(const_iterator, const_iterator)): Also update
_M_buckets[__n_bkt] if __is_bucket_begin.
* testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc:
New test.
From-SVN: r183300
-rw-r--r-- | libstdc++-v3/ChangeLog | 9 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/hashtable.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc | 72 |
3 files changed, 82 insertions, 1 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f805fd9..fa3523b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2012-01-19 Jakub Jelinek <jakub@redhat.com> + + PR libstdc++/51845 + * include/bits/hashtable.h + (_Hashtable<>::erase(const_iterator, const_iterator)): Also update + _M_buckets[__n_bkt] if __is_bucket_begin. + * testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc: + New test. + 2012-01-18 Benjamin Kosnik <bkoz@redhat.com> * acinclude (GLIBCXX_CONFIGURE_DOCBOOK): Fix quoting. diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index c2ffae2..d4f2aed 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -1544,7 +1544,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __bkt = __n_bkt; } - if (__n && __n_bkt != __bkt) + if (__n && (__n_bkt != __bkt || __is_bucket_begin)) _M_buckets[__n_bkt] = __prev_n; __prev_n->_M_nxt = __n; return iterator(__n); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc new file mode 100644 index 0000000..450fb6f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/erase/51845-multimap.cc @@ -0,0 +1,72 @@ +// { dg-options "-std=gnu++0x" } + +// 2012-01-19 Jakub Jelinek <jakub@redhat.com> +// +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <unordered_map> +#include <testsuite_hooks.h> + +// libstdc++/51845 +void test01() +{ + bool test __attribute__((unused)) = true; + + typedef std::unordered_multimap<int, int> Mmap; + typedef Mmap::iterator iterator; + typedef Mmap::const_iterator const_iterator; + typedef Mmap::value_type value_type; + + Mmap mm1; + + mm1.insert(value_type(11135, 1)); + mm1.insert(value_type(11135, 17082)); + mm1.insert(value_type(9644, 24135)); + mm1.insert(value_type(9644, 9644)); + mm1.insert(value_type(13984, 19841)); + mm1.insert(value_type(9644, 1982)); + mm1.insert(value_type(13984, 1945)); + mm1.insert(value_type(7, 1982)); + mm1.insert(value_type(7, 1945)); + VERIFY( mm1.size() == 9 ); + + iterator it1 = mm1.begin(); + ++it1; + iterator it2 = it1; + ++it2; + ++it2; + iterator it3 = mm1.erase(it1, it2); + VERIFY( mm1.size() == 7 ); + VERIFY( it3 == it2 ); + VERIFY( *it3 == *it2 ); + + const_iterator it4 = mm1.begin(); + ++it4; + const_iterator it5 = it4; + ++it5; + const_iterator it6 = mm1.erase(it4); + VERIFY( mm1.size() == 6 ); + VERIFY( it6 == it5 ); + VERIFY( *it6 == *it5 ); +} + +int main() +{ + test01(); + return 0; +} |