aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-08-14 09:29:47 +0200
committerJakub Jelinek <jakub@redhat.com>2020-08-14 09:29:47 +0200
commit22dc89f8073cd0126efa72aa3ab88e80c78d45e3 (patch)
treeec8d221fabb79c0c923d80d87a368b3135f4d35b
parent5afd18820f4b72e1baa036db4d81d63cdf07ad68 (diff)
downloadgcc-22dc89f8073cd0126efa72aa3ab88e80c78d45e3.zip
gcc-22dc89f8073cd0126efa72aa3ab88e80c78d45e3.tar.gz
gcc-22dc89f8073cd0126efa72aa3ab88e80c78d45e3.tar.bz2
vec: Fix bootstrap on i686-linux, 32-bit darwin and AIX
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. 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. Co-Authored-By: Jonathan Wakely <jwakely@redhat.com>
-rw-r--r--gcc/system.h1
-rw-r--r--gcc/vec.h8
2 files changed, 6 insertions, 3 deletions
diff --git a/gcc/system.h b/gcc/system.h
index a241e13..3c543a0 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -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
diff --git a/gcc/vec.h b/gcc/vec.h
index db48e97..6ede627 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1283,9 +1283,11 @@ vec<T, A, vl_embed>::embedded_size (unsigned alloc)
{
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);
}