diff options
| author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-08 23:58:31 +0000 |
|---|---|---|
| committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-04-08 23:58:31 +0000 |
| commit | ccb35abbba4ea30b80e1875f53065f2788645385 (patch) | |
| tree | 9eda1fdbd680a5746db750c5fe831efce5cbd3ce /libstdc++-v3/include/backward | |
| parent | b8f4348b6179b66841c5127fae56a1e1b477222f (diff) | |
| download | ppe42-gcc-ccb35abbba4ea30b80e1875f53065f2788645385.tar.gz ppe42-gcc-ccb35abbba4ea30b80e1875f53065f2788645385.zip | |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145788 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/backward')
| -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; } |

