This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Patch committed: Fix erasing with reference in old hashtable code
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Wed, 25 May 2011 16:09:17 -0700
- Subject: Patch committed: Fix erasing with reference in old hashtable code
This patch fixes a problem with the old hashtable::erase code when the
caller passes a reference to an element in the table, the element is not
the first in the bucket, but it is equal to the first in the bucket.
This is PR 49060, and the patch and test case are from that PR with
minor tweaks. Bootstrapped and ran libstdc++ testsuite on
x86_64-unknown-linux-gnu. Committed to mainline.
Ian
2011-05-25 David Tardon <dtardon@redhat.com>
PR libstdc++/49060
* include/backward/hashtable.h (hashtable::erase): Don't crash if
erasing first and another element with a reference to the other
element.
* testsuite/backward/hash_set/49060.cc: New.
Index: include/backward/hashtable.h
===================================================================
--- include/backward/hashtable.h (revision 173685)
+++ include/backward/hashtable.h (working copy)
@@ -898,13 +898,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__next = __cur->_M_next;
}
}
- if (_M_equals(_M_get_key(__first->_M_val), __key))
- {
- _M_buckets[__n] = __first->_M_next;
- _M_delete_node(__first);
- ++__erased;
- --_M_num_elements;
- }
+ bool __delete_first = _M_equals(_M_get_key(__first->_M_val), __key);
if (__saved_slot)
{
__next = __saved_slot->_M_next;
@@ -913,6 +907,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
++__erased;
--_M_num_elements;
}
+ if (__delete_first)
+ {
+ _M_buckets[__n] = __first->_M_next;
+ _M_delete_node(__first);
+ ++__erased;
+ --_M_num_elements;
+ }
}
return __erased;
}
Index: testsuite/backward/hash_set/49060.cc
===================================================================
--- testsuite/backward/hash_set/49060.cc (revision 0)
+++ testsuite/backward/hash_set/49060.cc (revision 0)
@@ -0,0 +1,35 @@
+// { dg-options "-Wno-deprecated" }
+
+#include <backward/hashtable.h>
+#include <utility>
+
+struct modulo2_hash
+{
+ size_t operator()(int const key) const
+ {
+ return key % 2;
+ }
+};
+
+struct modulo2_eq
+{
+ bool operator()(int const left, int const right) const
+ {
+ return left % 2 == right % 2;
+ }
+};
+
+int main()
+{
+ typedef std::_Select1st<std::pair<int const, int> > extract_type;
+ typedef
+ __gnu_cxx::hashtable<std::pair<int const, int>, int, modulo2_hash,
+ extract_type, modulo2_eq, std::allocator<int> >
+ table_type;
+ table_type table(4, modulo2_hash(), modulo2_eq(), extract_type(),
+ std::allocator<int>());
+
+ table.insert_equal(std::make_pair(2, 1));
+ table_type::iterator it(table.insert_equal(std::make_pair(4, 2)));
+ table.erase(it->first);
+}