On Fri, Feb 16, 2018 at 10:36:27AM -0700, Martin Sebor wrote:
> The deeper problem is that vec wants to be a POD but GCC
> instantiates the template on non-POD types.  For example
> genrecog.c instantiates it on struct parameter that has
> a default ctor.
> 
> A number of ipa-*.c files instantiate vec on ipa_polymorphic_call_context,
> which also has a default ctor,
> and ctor even has different semantics than memset (it sets
> a few members to non-zero).  So calling memset here instead
> of the default ctor could be a potential bug.

Then we should just call memset and then do the placement new for older
compilers (those certainly didn't have -flifetime-dse=2, so wouldn't throw
away whatever has been there before the ctor), or just fix up
ipa_polymorphic_call_context so that default ctor clears everything rather
than setting something to true.

In any case, I hope we don't grow too many new uses of value initialization
which is so problematic in older compilers.

Here is what I'll test.  AFAIK both the *something = value_init ();
and ::new (ptr) value_init (); work even in the buggy compilers, including
4.2.[0-3], if value_init has user defined default ctor, just call
that default ctor and do nothing else, the mishandled cases are only for
classes without those.  So it will be enough to make sure we don't create
hash maps of types that need something non-zero in default ctor or put such
types into classes without user provided default ctor.

2018-02-16  Jakub Jelinek  <ja...@redhat.com>

        PR bootstrap/84405
        * vec.h (vec_default_construct): For BROKEN_VALUE_INITIALIZATION use
        memset and value initialization afterwards.
        * hash-table.h (hash_table<Descriptor, Allocator>::empty_slow):
        Likewise.

--- gcc/hash-table.h.jj 2018-02-16 10:04:25.179740963 +0100
+++ gcc/hash-table.h    2018-02-16 18:48:38.359845266 +0100
@@ -804,12 +804,11 @@ hash_table<Descriptor, Allocator>::empty
     }
   else
     {
-#ifndef BROKEN_VALUE_INITIALIZATION
-      for ( ; size; ++entries, --size)
-       *entries = value_type ();
-#else
+#ifdef BROKEN_VALUE_INITIALIZATION
       memset (entries, 0, size * sizeof (value_type));
 #endif
+      for ( ; size; ++entries, --size)
+       *entries = value_type ();
     }
   m_n_deleted = 0;
   m_n_elements = 0;
--- gcc/vec.h.jj        2018-02-16 10:04:25.178740963 +0100
+++ gcc/vec.h   2018-02-16 18:49:21.305850964 +0100
@@ -490,12 +490,11 @@ template <typename T>
 inline void
 vec_default_construct (T *dst, unsigned n)
 {
-#ifndef BROKEN_VALUE_INITIALIZATION
-  for ( ; n; ++dst, --n)
-    ::new (static_cast<void*>(dst)) T ();
-#else
+#ifdef BROKEN_VALUE_INITIALIZATION
   memset (dst, '\0', sizeof (T) * n);
 #endif
+  for ( ; n; ++dst, --n)
+    ::new (static_cast<void*>(dst)) T ();
 }
 
 /* Copy-construct N elements in DST from *SRC.  */


        Jakub

Reply via email to