From: Martin Sebor Date: Mon, 9 Dec 2019 20:54:11 +0000 (+0000) Subject: PR middle-end/92761 - hash_table::expand invokes assignment on invalid objects X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49070d06708a8d8ae3af767f89ac40c4c12dca7b;p=gcc.git PR middle-end/92761 - hash_table::expand invokes assignment on invalid objects PR middle-end/92761 - hash_table::expand invokes assignment on invalid objects PR middle-end/92762 - hash_table::empty_slow invokes assignment on invalid objects gcc/ChangeLog: PR middle-end/92761 PR middle-end/92762 * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Tighten up tests. * hash-table.h (hash_table::expand): Use placement new to copy construct objects in uninitialized storage. (hash_table::empty_slow): Avoid invoking copy assignment on uninitialized objects. From-SVN: r279139 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f5b06d8be3..0a0336268e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-12-09 Martin Sebor + + PR middle-end/92761 + PR middle-end/92762 + * hash-map-tests.c (test_map_of_type_with_ctor_and_dtor): Tighten + up tests. + * hash-table.h (hash_table::expand): Use placement new to copy + construct objects in uninitialized storage. + (hash_table::empty_slow): Avoid invoking copy assignment on + uninitialized objects. + 2019-12-09 Lewis Hyatt PR preprocessor/49973 diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c index f3b216be07c..a42eac21ab3 100644 --- a/gcc/hash-map-tests.c +++ b/gcc/hash-map-tests.c @@ -117,23 +117,26 @@ public: ++ndefault; } - hash_map_test_val_t (const hash_map_test_val_t &) + hash_map_test_val_t (const hash_map_test_val_t &rhs) : ptr (&ptr) { ++ncopy; + gcc_assert (rhs.ptr == &rhs.ptr); } - hash_map_test_val_t& operator= (const hash_map_test_val_t &) - { - ++nassign; - return *this; - } + hash_map_test_val_t& operator= (const hash_map_test_val_t &rhs) + { + ++nassign; + gcc_assert (ptr == &ptr); + gcc_assert (rhs.ptr == &rhs.ptr); + return *this; + } ~hash_map_test_val_t () - { - gcc_assert (ptr == &ptr); - ++ndtor; - } + { + gcc_assert (ptr == &ptr); + ++ndtor; + } void *ptr; } val_t; @@ -184,7 +187,6 @@ test_map_of_type_with_ctor_and_dtor () ASSERT_TRUE (nassign == val_t::nassign); ASSERT_TRUE (&rv1 != pv2); - ASSERT_TRUE (pv2->ptr == &pv2->ptr); } ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); @@ -207,7 +209,6 @@ test_map_of_type_with_ctor_and_dtor () ASSERT_TRUE (nassign + 1 == val_t::nassign); ASSERT_TRUE (&rv1 != pv2); - ASSERT_TRUE (pv2->ptr == &pv2->ptr); } ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); diff --git a/gcc/hash-table.h b/gcc/hash-table.h index ba5d64fb7a3..26bac624a08 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -818,8 +818,7 @@ hash_table::expand () if (!is_empty (x) && !is_deleted (x)) { value_type *q = find_empty_slot_for_expand (Descriptor::hash (x)); - - *q = x; + new ((void*) q) value_type (x); } p++; @@ -869,14 +868,8 @@ hash_table::empty_slow () m_size_prime_index = nindex; } else - { -#ifndef BROKEN_VALUE_INITIALIZATION - for ( ; size; ++entries, --size) - *entries = value_type (); -#else - memset (entries, 0, size * sizeof (value_type)); -#endif - } + memset ((void *) entries, 0, size * sizeof (value_type)); + m_n_deleted = 0; m_n_elements = 0; }