PR libstdc++/90046 fix build failure on epiphany-elf
authorJonathan Wakely <jwakely@redhat.com>
Thu, 11 Apr 2019 19:58:14 +0000 (20:58 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 11 Apr 2019 19:58:14 +0000 (20:58 +0100)
The epiphany-elf target aligns structs to 8 bytes, which causes the
static_assert(alignof(_Chunk) == 1) to fail.

Instead of requiring _Chunks to be positionable at any alignment, ensure
new buffers are aligned to alignof(_Chunk). Because the buffer size is a
power of two, we know that both the buffer size and sizeof(_Chunk) are
multiples of alignof(_Chunk). So is p is aligned to alignof(_Chunk) then
so is (p + size - sizeof(_Chunk)). So just ensure the new buffer is
aligned to at least alignof(_Chunk), which should already be true
because the caller requests at least alignof(max_align_t).

PR libstdc++/90046
* src/c++17/memory_resource.cc
(monotonic_buffer_resource::_Chunk::allocate): Increase alignment if
needed to allow placing a _Chunk at the end of the buffer.
(monotonic_buffer_resource::_M_new_buffer): Remove static_assert.

From-SVN: r270291

libstdc++-v3/ChangeLog
libstdc++-v3/src/c++17/memory_resource.cc

index 6148f5c..d49ce7c 100644 (file)
@@ -1,3 +1,11 @@
+2019-04-11  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/90046
+       * src/c++17/memory_resource.cc
+       (monotonic_buffer_resource::_Chunk::allocate): Increase alignment if
+       needed to allow placing a _Chunk at the end of the buffer.
+       (monotonic_buffer_resource::_M_new_buffer): Remove static_assert.
+
 2019-04-10  Jonathan Wakely  <jwakely@redhat.com>
 
        * doc/xml/faq.xml: Add information about emergency EH pool.
index cd11bf5..b669801 100644 (file)
@@ -182,7 +182,21 @@ namespace pmr
             _Chunk*& __head)
     {
       __size = std::__ceil2(__size + sizeof(_Chunk));
+
+      if constexpr (alignof(_Chunk) > 1)
+       {
+         // PR libstdc++/90046
+         // For targets like epiphany-elf where alignof(_Chunk) != 1
+         // ensure that the last sizeof(_Chunk) bytes in the buffer
+         // are suitably-aligned for a _Chunk.
+         // This should be unnecessary, because the caller already
+         // passes in max(__align, alignof(max_align_t)).
+         if (__align < alignof(_Chunk))
+           __align = alignof(_Chunk);
+       }
+
       void* __p = __r->allocate(__size, __align);
+
       // Add a chunk defined by (__p, __size, __align) to linked list __head.
       void* const __back = (char*)__p + __size - sizeof(_Chunk);
       __head = ::new(__back) _Chunk(__size, __align, __head);
@@ -231,9 +245,6 @@ namespace pmr
   void
   monotonic_buffer_resource::_M_new_buffer(size_t bytes, size_t alignment)
   {
-    // Need to check this somewhere, so put it here:
-    static_assert(alignof(monotonic_buffer_resource::_Chunk) == 1);
-
     const size_t n = std::max(bytes, _M_next_bufsiz);
     const size_t m = std::max(alignment, alignof(std::max_align_t));
     auto [p, size] = _Chunk::allocate(_M_upstream, n, m, _M_head);