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-tests.c | |
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-tests.c')
-rw-r--r-- | gcc/hash-map-tests.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c index b79c782..5888f25 100644 --- a/gcc/hash-map-tests.c +++ b/gcc/hash-map-tests.c @@ -103,12 +103,146 @@ test_map_of_strings_to_int () ASSERT_EQ (1, string_map.elements ()); } +typedef struct hash_map_test_val_t +{ + static int ndefault; + static int ncopy; + static int nassign; + static int ndtor; + + hash_map_test_val_t () + : ptr (&ptr) + { + ++ndefault; + } + + hash_map_test_val_t (const hash_map_test_val_t &) + : ptr (&ptr) + { + ++ncopy; + } + + hash_map_test_val_t& operator= (const hash_map_test_val_t &) + { + ++nassign; + return *this; + } + + ~hash_map_test_val_t () + { + gcc_assert (ptr == &ptr); + ++ndtor; + } + + void *ptr; +} val_t; + +int val_t::ndefault; +int val_t::ncopy; +int val_t::nassign; +int val_t::ndtor; + +static void +test_map_of_type_with_ctor_and_dtor () +{ + typedef hash_map <void *, val_t> Map; + + { + /* Test default ctor. */ + Map m; + (void)&m; + } + + ASSERT_TRUE (val_t::ndefault == 0); + ASSERT_TRUE (val_t::ncopy == 0); + ASSERT_TRUE (val_t::nassign == 0); + ASSERT_TRUE (val_t::ndtor == 0); + + { + /* Test single insertion. */ + Map m; + void *p = &p; + m.get_or_insert (p); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + + { + /* Test copy ctor. */ + Map m1; + void *p = &p; + val_t &rv1 = m1.get_or_insert (p); + + int ncopy = val_t::ncopy; + int nassign = val_t::nassign; + + Map m2 (m1); + val_t *pv2 = m2.get (p); + + ASSERT_TRUE (ncopy + 1 == val_t::ncopy); + 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); + +#if 0 /* Avoid testing until bug 90959 is fixed. */ + { + /* Test copy assignment into an empty map. */ + Map m1; + void *p = &p; + val_t &rv1 = m1.get_or_insert (p); + + int ncopy = val_t::ncopy; + int nassign = val_t::nassign; + + Map m2; + m2 = m1; + val_t *pv2 = m2.get (p); + + ASSERT_TRUE (ncopy == val_t::ncopy); + 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); + +#endif + + { + Map m; + void *p = &p, *q = &q; + val_t &v1 = m.get_or_insert (p); + val_t &v2 = m.get_or_insert (q); + + ASSERT_TRUE (v1.ptr == &v1.ptr && &v2.ptr == v2.ptr); + } + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + + { + Map m; + void *p = &p, *q = &q; + m.get_or_insert (p); + m.remove (p); + m.get_or_insert (q); + m.remove (q); + + ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor); + } +} + /* Run all of the selftests within this file. */ void hash_map_tests_c_tests () { test_map_of_strings_to_int (); + test_map_of_type_with_ctor_and_dtor (); } } // namespace selftest |