aboutsummaryrefslogtreecommitdiff
path: root/gcc/hash-map.h
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-07-01 18:33:36 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-07-01 12:33:36 -0600
commit7b8795a138d0baa3b0505baee2ed05ae266977cd (patch)
tree74e86b5944db91f0d3068ed61906a8a389b0cf42 /gcc/hash-map.h
parent25cd9afbc1dc6bd9d4afccab3f09f0fbc811291a (diff)
downloadgcc-7b8795a138d0baa3b0505baee2ed05ae266977cd.zip
gcc-7b8795a138d0baa3b0505baee2ed05ae266977cd.tar.gz
gcc-7b8795a138d0baa3b0505baee2ed05ae266977cd.tar.bz2
PR middle-end/90923 - hash_map destroys elements without constructing them
gcc/ChangeLog: PR middle-end/90923 * hash-map.h (hash_map::put): On insertion invoke element ctor. (hash_map::get_or_insert): Same. Reformat comment. * hash-set.h (hash_set::add): On insertion invoke element ctor. * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): New. * hash-set-tests.c (test_map_of_type_with_ctor_and_dtor): New. * hash-table.h (hash_table::operator=): Prevent copy assignment. (hash_table::hash_table (const hash_table&)): Use copy ctor instead of assignment to copy elements. From-SVN: r272893
Diffstat (limited to 'gcc/hash-map.h')
-rw-r--r--gcc/hash-map.h37
1 files changed, 28 insertions, 9 deletions
diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index 588dfda..f3f1f9a 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -21,8 +21,20 @@ along with GCC; see the file COPYING3. If not see
#ifndef hash_map_h
#define hash_map_h
+/* Class hash_map is a hash-value based container mapping objects of
+ KeyId type to those of the Value type.
+ Both KeyId and Value may be non-trivial (non-POD) types provided
+ a suitabe Traits class. A few default Traits specializations are
+ provided for basic types such as integers, pointers, and std::pair.
+ Inserted elements are value-initialized either to zero for POD types
+ or by invoking their default ctor. Removed elements are destroyed
+ by invoking their dtor. On hash_map destruction all elements are
+ removed. Objects of hash_map type are copy-constructible but not
+ assignable. */
+
template<typename KeyId, typename Value,
- typename Traits>
+ typename Traits /* = simple_hashmap_traits<default_hash_traits<Key>,
+ Value> */>
class GTY((user)) hash_map
{
typedef typename Traits::key_type Key;
@@ -151,12 +163,16 @@ public:
{
hash_entry *e = m_table.find_slot_with_hash (k, Traits::hash (k),
INSERT);
- bool existed = !hash_entry::is_empty (*e);
- if (!existed)
- e->m_key = k;
+ bool ins = hash_entry::is_empty (*e);
+ if (ins)
+ {
+ e->m_key = k;
+ new ((void *) &e->m_value) Value (v);
+ }
+ else
+ e->m_value = v;
- e->m_value = v;
- return existed;
+ return !ins;
}
/* if the passed in key is in the map return its value otherwise NULL. */
@@ -168,8 +184,8 @@ public:
}
/* Return a reference to the value for the passed in key, creating the entry
- if it doesn't already exist. If existed is not NULL then it is set to false
- if the key was not previously in the map, and true otherwise. */
+ if it doesn't already exist. If existed is not NULL then it is set to
+ false if the key was not previously in the map, and true otherwise. */
Value &get_or_insert (const Key &k, bool *existed = NULL)
{
@@ -177,7 +193,10 @@ public:
INSERT);
bool ins = Traits::is_empty (*e);
if (ins)
- e->m_key = k;
+ {
+ e->m_key = k;
+ new ((void *)&e->m_value) Value ();
+ }
if (existed != NULL)
*existed = !ins;