diff options
author | Martin Sebor <msebor@redhat.com> | 2019-07-01 18:33:36 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-07-01 12:33:36 -0600 |
commit | 7b8795a138d0baa3b0505baee2ed05ae266977cd (patch) | |
tree | 74e86b5944db91f0d3068ed61906a8a389b0cf42 /gcc/hash-map.h | |
parent | 25cd9afbc1dc6bd9d4afccab3f09f0fbc811291a (diff) | |
download | gcc-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.h | 37 |
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; |