diff options
author | Ian Lance Taylor <iant@google.com> | 2009-04-08 23:58:31 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-04-08 23:58:31 +0000 |
commit | 9767a048ab7225f4b4a01f8f506bb2bf97aadaab (patch) | |
tree | 9eda1fdbd680a5746db750c5fe831efce5cbd3ce /libstdc++-v3/include/backward/hashtable.h | |
parent | 0b83c44bdf9431f7933eb8aa28f9a33efe453722 (diff) | |
download | gcc-9767a048ab7225f4b4a01f8f506bb2bf97aadaab.tar.gz |
hashtable.h (erase): Correctly handle erasing a reference to an entry in the hash table.
* include/backward/hashtable.h (erase): Correctly handle erasing a
reference to an entry in the hash table.
* testsuite/backward/hash_map/25896.cc: New.
* testsuite/backward/hash_set/25896.cc: New.
From-SVN: r145788
Diffstat (limited to 'libstdc++-v3/include/backward/hashtable.h')
-rw-r--r-- | libstdc++-v3/include/backward/hashtable.h | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/libstdc++-v3/include/backward/hashtable.h b/libstdc++-v3/include/backward/hashtable.h index e0ba83b34f1..cfa6f06a913 100644 --- a/libstdc++-v3/include/backward/hashtable.h +++ b/libstdc++-v3/include/backward/hashtable.h @@ -869,8 +869,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { const size_type __n = _M_bkt_num_key(__key); _Node* __first = _M_buckets[__n]; + _Node* __saved_slot = 0; size_type __erased = 0; - + if (__first) { _Node* __cur = __first; @@ -879,11 +880,20 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { if (_M_equals(_M_get_key(__next->_M_val), __key)) { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - ++__erased; - --_M_num_elements; + if (&_M_get_key(__next->_M_val) != &__key) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else + { + __saved_slot = __cur; + __cur = __next; + __next = __cur->_M_next; + } } else { @@ -898,6 +908,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) ++__erased; --_M_num_elements; } + if (__saved_slot) + { + __next = __saved_slot->_M_next; + __saved_slot->_M_next = __next->_M_next; + _M_delete_node(__next); + ++__erased; + --_M_num_elements; + } } return __erased; } |