Commit 49070d06 by Martin Sebor Committed by Martin Sebor

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
parent ca6932ad
2019-12-09 Martin Sebor <msebor@redhat.com>
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 <lhyatt@gmail.com> 2019-12-09 Lewis Hyatt <lhyatt@gmail.com>
PR preprocessor/49973 PR preprocessor/49973
...@@ -117,23 +117,26 @@ public: ...@@ -117,23 +117,26 @@ public:
++ndefault; ++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) : ptr (&ptr)
{ {
++ncopy; ++ncopy;
gcc_assert (rhs.ptr == &rhs.ptr);
} }
hash_map_test_val_t& operator= (const hash_map_test_val_t &) hash_map_test_val_t& operator= (const hash_map_test_val_t &rhs)
{ {
++nassign; ++nassign;
return *this; gcc_assert (ptr == &ptr);
} gcc_assert (rhs.ptr == &rhs.ptr);
return *this;
}
~hash_map_test_val_t () ~hash_map_test_val_t ()
{ {
gcc_assert (ptr == &ptr); gcc_assert (ptr == &ptr);
++ndtor; ++ndtor;
} }
void *ptr; void *ptr;
} val_t; } val_t;
...@@ -184,7 +187,6 @@ test_map_of_type_with_ctor_and_dtor () ...@@ -184,7 +187,6 @@ test_map_of_type_with_ctor_and_dtor ()
ASSERT_TRUE (nassign == val_t::nassign); ASSERT_TRUE (nassign == val_t::nassign);
ASSERT_TRUE (&rv1 != pv2); ASSERT_TRUE (&rv1 != pv2);
ASSERT_TRUE (pv2->ptr == &pv2->ptr);
} }
ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
...@@ -207,7 +209,6 @@ test_map_of_type_with_ctor_and_dtor () ...@@ -207,7 +209,6 @@ test_map_of_type_with_ctor_and_dtor ()
ASSERT_TRUE (nassign + 1 == val_t::nassign); ASSERT_TRUE (nassign + 1 == val_t::nassign);
ASSERT_TRUE (&rv1 != pv2); ASSERT_TRUE (&rv1 != pv2);
ASSERT_TRUE (pv2->ptr == &pv2->ptr);
} }
ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
......
...@@ -818,8 +818,7 @@ hash_table<Descriptor, Lazy, Allocator>::expand () ...@@ -818,8 +818,7 @@ hash_table<Descriptor, Lazy, Allocator>::expand ()
if (!is_empty (x) && !is_deleted (x)) if (!is_empty (x) && !is_deleted (x))
{ {
value_type *q = find_empty_slot_for_expand (Descriptor::hash (x)); value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
new ((void*) q) value_type (x);
*q = x;
} }
p++; p++;
...@@ -869,14 +868,8 @@ hash_table<Descriptor, Lazy, Allocator>::empty_slow () ...@@ -869,14 +868,8 @@ hash_table<Descriptor, Lazy, Allocator>::empty_slow ()
m_size_prime_index = nindex; m_size_prime_index = nindex;
} }
else else
{ memset ((void *) entries, 0, size * sizeof (value_type));
#ifndef BROKEN_VALUE_INITIALIZATION
for ( ; size; ++entries, --size)
*entries = value_type ();
#else
memset (entries, 0, size * sizeof (value_type));
#endif
}
m_n_deleted = 0; m_n_deleted = 0;
m_n_elements = 0; m_n_elements = 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment