diff mbox series

vec: Fix bootstrap on i686-linux, 32-bit darwin and AIX

Message ID 20200814065855.GL2363@tucnak
State New
Headers show
Series vec: Fix bootstrap on i686-linux, 32-bit darwin and AIX | expand

Commit Message

Jakub Jelinek Aug. 14, 2020, 6:58 a.m. UTC
Hi!

As mentioned earlier, embedded_size is broken on vecs of long long, double
etc. on some platforms, which breaks bootstrap.
E.g. on i686-linux, the problem is mostly with older GCC versions being used
as stage1 compiler (GCC 4.8 to 7.* in particular), because alignas (long long)
makes U 64-bit aligned, while when long long m_vecdata[1]; is in vec, it is
only 32-bit aligned.  We've tried various ways and the following one seems
to work, use the old way (offsetof (vec, m_vecdata)) for non-class types
as well as standard layout class types, i.e. whenever offsetof is guaranteed
to work, and for others use the new day (in that case we don't run into
problems with long long or other scalar types and for the structure layout
there is just a struct with a given alignment.

Bootstrapped/regtested on x86_64-linux and i686-linux, AFAIK Iain and David
are bootstrapping/regtesting it on 32-bit darwin and AIX and it got through
the spots where it broke before, ok for trunk?

2020-08-14  Jakub Jelinek  <jakub@redhat.com>
	    Jonathan Wakely  <jwakely@redhat.com>

	* system.h: Include type_traits.
	* vec.h (vec<T, A, vl_embed>::embedded_size): Use offsetof and asserts
	on vec_stdlayout, which is conditionally a vec (for standard layout T)
	and otherwise vec_embedded.


	Jakub

Comments

Richard Biener Aug. 14, 2020, 7:14 a.m. UTC | #1
On August 14, 2020 8:58:55 AM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>As mentioned earlier, embedded_size is broken on vecs of long long,
>double
>etc. on some platforms, which breaks bootstrap.
>E.g. on i686-linux, the problem is mostly with older GCC versions being
>used
>as stage1 compiler (GCC 4.8 to 7.* in particular), because alignas
>(long long)
>makes U 64-bit aligned, while when long long m_vecdata[1]; is in vec,
>it is
>only 32-bit aligned.  We've tried various ways and the following one
>seems
>to work, use the old way (offsetof (vec, m_vecdata)) for non-class
>types
>as well as standard layout class types, i.e. whenever offsetof is
>guaranteed
>to work, and for others use the new day (in that case we don't run into
>problems with long long or other scalar types and for the structure
>layout
>there is just a struct with a given alignment.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, AFAIK Iain and
>David
>are bootstrapping/regtesting it on 32-bit darwin and AIX and it got
>through
>the spots where it broke before, ok for trunk?

OK. 

Thanks, 
Richard. 

>2020-08-14  Jakub Jelinek  <jakub@redhat.com>
>	    Jonathan Wakely  <jwakely@redhat.com>
>
>	* system.h: Include type_traits.
>	* vec.h (vec<T, A, vl_embed>::embedded_size): Use offsetof and asserts
>	on vec_stdlayout, which is conditionally a vec (for standard layout T)
>	and otherwise vec_embedded.
>
>--- gcc/system.h.jj	2020-07-28 15:39:09.984756558 +0200
>+++ gcc/system.h	2020-08-13 16:33:48.330642026 +0200
>@@ -235,6 +235,7 @@ extern int errno;
> # include <cstring>
> # include <new>
> # include <utility>
>+# include <type_traits>
> #endif
> 
> /* Some of glibc's string inlines cause warnings.  Plus we'd rather
>--- gcc/vec.h.jj	2020-08-13 15:41:17.221755055 +0200
>+++ gcc/vec.h	2020-08-13 16:31:42.190367975 +0200
>@@ -1283,9 +1283,11 @@ vec<T, A, vl_embed>::embedded_size (unsi
> {
>   struct alignas (T) U { char data[sizeof (T)]; };
>   typedef vec<U, A, vl_embed> vec_embedded;
>-  static_assert (sizeof (vec_embedded) == sizeof(vec), "");
>-  static_assert (alignof (vec_embedded) == alignof(vec), "");
>-  return offsetof (vec_embedded, m_vecdata) + alloc * sizeof (T);
>+  typedef typename std::conditional<std::is_standard_layout<T>::value,
>+				    vec, vec_embedded>::type vec_stdlayout;
>+  static_assert (sizeof (vec_stdlayout) == sizeof (vec), "");
>+  static_assert (alignof (vec_stdlayout) == alignof (vec), "");
>+  return offsetof (vec_stdlayout, m_vecdata) + alloc * sizeof (T);
> }
> 
> 
>
>	Jakub
diff mbox series

Patch

--- gcc/system.h.jj	2020-07-28 15:39:09.984756558 +0200
+++ gcc/system.h	2020-08-13 16:33:48.330642026 +0200
@@ -235,6 +235,7 @@  extern int errno;
 # include <cstring>
 # include <new>
 # include <utility>
+# include <type_traits>
 #endif
 
 /* Some of glibc's string inlines cause warnings.  Plus we'd rather
--- gcc/vec.h.jj	2020-08-13 15:41:17.221755055 +0200
+++ gcc/vec.h	2020-08-13 16:31:42.190367975 +0200
@@ -1283,9 +1283,11 @@  vec<T, A, vl_embed>::embedded_size (unsi
 {
   struct alignas (T) U { char data[sizeof (T)]; };
   typedef vec<U, A, vl_embed> vec_embedded;
-  static_assert (sizeof (vec_embedded) == sizeof(vec), "");
-  static_assert (alignof (vec_embedded) == alignof(vec), "");
-  return offsetof (vec_embedded, m_vecdata) + alloc * sizeof (T);
+  typedef typename std::conditional<std::is_standard_layout<T>::value,
+				    vec, vec_embedded>::type vec_stdlayout;
+  static_assert (sizeof (vec_stdlayout) == sizeof (vec), "");
+  static_assert (alignof (vec_stdlayout) == alignof (vec), "");
+  return offsetof (vec_stdlayout, m_vecdata) + alloc * sizeof (T);
 }