PR middle-end/92761 - hash_table::expand invokes assignment on invalid objects
authorMartin Sebor <msebor@redhat.com>
Mon, 9 Dec 2019 20:54:11 +0000 (20:54 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Mon, 9 Dec 2019 20:54:11 +0000 (13:54 -0700)
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

gcc/ChangeLog
gcc/hash-map-tests.c
gcc/hash-table.h

index 8f5b06d8be31447272243a533fe804590cdf1507..0a0336268e275f9d754777ed858c013dc582f8b3 100644 (file)
@@ -1,3 +1,14 @@
+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>
 
        PR preprocessor/49973
index f3b216be07ca8304991cc17d8e1446667c2ef1ee..a42eac21ab36b58331cba5278e2ea3c5402e8f3d 100644 (file)
@@ -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);
index ba5d64fb7a319446fc5c5f2b704a93fab299b0f9..26bac624a082f5e0b8b19b8af733a64f44fbc0d4 100644 (file)
@@ -818,8 +818,7 @@ hash_table<Descriptor, Lazy, Allocator>::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<Descriptor, Lazy, Allocator>::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;
 }