This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix bootstrap with GCC 3.4 (and likely anything < 4.4 except 4.2.[0-3]) (PR bootstrap/84405)


On 02/16/2018 11:05 AM, Jakub Jelinek wrote:
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.

As a workaround for the GCC 4.2 bug it makes sense to me.

There was a proposal not so long ago to adopt C++ 11 that, if
I recall, had broad support.  That would make the minimum GCC
version 4.8 and the question of relying on value initialization
(hopefully) moot.  It should also make it easier to make use
of classes like vec with near-trivial types with ctors.  I'm
hoping it can be revisited in stage 1.  Ultimately, we need
to decide if vec really needs to be a POD (or trivial or
whatever), and if so, avoid instantiating it on non-PODs
(or non-trivial whatevers) and add a static assertion to
its interface to enforce it.

Martin


2018-02-16  Jakub Jelinek  <jakub@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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]