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