PR libstdc++/77691 increase allocation size to at least alignment
authorJonathan Wakely <jwakely@redhat.com>
Thu, 11 Oct 2018 23:21:11 +0000 (00:21 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 11 Oct 2018 23:21:11 +0000 (00:21 +0100)
It's not safe to assume that malloc(n) returns memory aligned to more
than n, so when relying on the guaranteed alignment of malloc ensure
that the number of bytes allocated is at least as large as the
alignment.

PR libstdc++/77691
* include/experimental/memory_resource (__resource_adaptor_imp): Do
not allocate sizes smaller than alignment when relying on guaranteed
alignment.
* testsuite/experimental/memory_resource/new_delete_resource.cc:
Adjust expected number of bytes allocated for alignof(max_align_t).

From-SVN: r265068

libstdc++-v3/ChangeLog
libstdc++-v3/include/experimental/memory_resource
libstdc++-v3/testsuite/experimental/memory_resource/new_delete_resource.cc

index 93293c0631a4285747989d9187969450babe555a..35be45e4e461d747370836e48f33ce9fefa89cf4 100644 (file)
@@ -1,3 +1,12 @@
+2018-10-12  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/77691
+       * include/experimental/memory_resource (__resource_adaptor_imp): Do
+       not allocate sizes smaller than alignment when relying on guaranteed
+       alignment.
+       * testsuite/experimental/memory_resource/new_delete_resource.cc:
+       Adjust expected number of bytes allocated for alignof(max_align_t).
+
 2018-10-11  François Dumont  <fdumont@gcc.gnu.org>
 
        * include/debug/forward_list
index ccb45bfa33542ca758385060a961512b3b455ffc..fd40d2cf45b7e8eeafe7dc7e5e4d68761b21a328 100644 (file)
@@ -421,7 +421,12 @@ namespace pmr {
       do_allocate(size_t __bytes, size_t __alignment) override
       {
        if (__alignment <= __guaranteed_alignment<_Alloc>::value)
-         return _M_alloc.allocate(__bytes);
+         {
+           if (__bytes < __alignment)
+             __bytes = __alignment;
+           return _M_alloc.allocate(__bytes);
+         }
+
 
        const _AlignMgr __mgr(__bytes, __alignment);
        // Assume _M_alloc returns 1-byte aligned memory, so allocate enough
@@ -437,6 +442,8 @@ namespace pmr {
        auto __ptr = static_cast<char*>(__p);
        if (__alignment <= __guaranteed_alignment<_Alloc>::value)
          {
+           if (__bytes < __alignment)
+             __bytes = __alignment;
            _M_alloc.deallocate(__ptr, __bytes);
            return;
          }
index 11667b1d138f0450e05c127966f8a0f12fcb0b66..3af3861d1a0c1b406580f0a7ed57e64b2dfa4099 100644 (file)
@@ -109,11 +109,13 @@ test03()
   using std::size_t;
   void* p = nullptr;
 
+  auto max = [](int n, int a) { return n > a ? n : a; };
+
   bytes_allocated = 0;
 
   memory_resource* r1 = new_delete_resource();
-  p = r1->allocate(1);
-  VERIFY( bytes_allocated == 1 );
+  p = r1->allocate(1); // uses alignment = alignof(max_align_t)
+  VERIFY( bytes_allocated <= alignof(max_align_t) );
   VERIFY( aligned<max_align_t>(p) );
   r1->deallocate(p, 1);
   VERIFY( bytes_allocated == 0 );
@@ -125,13 +127,13 @@ test03()
   VERIFY( bytes_allocated == 0 );
 
   p = r1->allocate(3, alignof(short));
-  VERIFY( bytes_allocated == 3 );
+  VERIFY( bytes_allocated == max(3, alignof(short)) );
   VERIFY( aligned<short>(p) );
   r1->deallocate(p, 3, alignof(short));
   VERIFY( bytes_allocated == 0 );
 
   p = r1->allocate(4, alignof(long));
-  VERIFY( bytes_allocated == 4 );
+  VERIFY( bytes_allocated == max(4, alignof(long)) );
   VERIFY( aligned<long>(p) );
   r1->deallocate(p, 4, alignof(long));
   VERIFY( bytes_allocated == 0 );