diff mbox

[1/2] libstdc++: Add std::align.

Message ID 20141013130408.GO4197@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Oct. 13, 2014, 1:04 p.m. UTC
On 13/10/14 13:10 +0100, Jonathan Wakely wrote:
>On 13/10/14 12:35 +0200, RĂ¼diger Sonderfeld wrote:
>>On Monday 13 October 2014 11:03:51 Jonathan Wakely wrote:
>>>Fixed (the new function should be in namespace std!) and applied to
>>>trunk. Thanks for the patch.
>>
>>Thanks for merging and improving my patches!
>>
>>If you have the time maybe you could also look at the put_time patch.  Unlike
>>get_time it does not require an ABI change.
>
>I was about to close https://gcc.gnu.org/PR57350 as fixed, but the
>test in the SO question it links to fails with your implementation
>that I've just committed:
>
>https://stackoverflow.com/questions/16305311/usage-issue-of-stdalign

I'm testing this fix.

Comments

Jonathan Wakely Oct. 13, 2014, 2:19 p.m. UTC | #1
On 13/10/14 14:04 +0100, Jonathan Wakely wrote:
>On 13/10/14 13:10 +0100, Jonathan Wakely wrote:
>>On 13/10/14 12:35 +0200, RĂ¼diger Sonderfeld wrote:
>>>On Monday 13 October 2014 11:03:51 Jonathan Wakely wrote:
>>>>Fixed (the new function should be in namespace std!) and applied to
>>>>trunk. Thanks for the patch.
>>>
>>>Thanks for merging and improving my patches!
>>>
>>>If you have the time maybe you could also look at the put_time patch.  Unlike
>>>get_time it does not require an ABI change.
>>
>>I was about to close https://gcc.gnu.org/PR57350 as fixed, but the
>>test in the SO question it links to fails with your implementation
>>that I've just committed:
>>
>>https://stackoverflow.com/questions/16305311/usage-issue-of-stdalign
>
>I'm testing this fix.

Committed to trunk.

>commit 60aa345d8122053f7c8ba7c743b458e799eb1455
>Author: Jonathan Wakely <jwakely@redhat.com>
>Date:   Mon Oct 13 14:02:39 2014 +0100
>
>    	PR libstdc++/57350
>    	* include/std/memory (align): Do not adjust correctly aligned address.
>    	* testsuite/20_util/align/2.cc: New.
>
>diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
>index affc8b1..b5792ad 100644
>--- a/libstdc++-v3/include/std/memory
>+++ b/libstdc++-v3/include/std/memory
>@@ -113,14 +113,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> inline void*
> align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
> {
>-  const size_t __diff = __align - reinterpret_cast<uintptr_t>(__ptr) % __align;
>-  if (__diff + __size >= __space)
>+  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
>+  const auto __aligned = (__intptr - 1u + __align) & -__align;
>+  const auto __diff = __aligned - __intptr;
>+  if ((__size + __diff) > __space)
>     return nullptr;
>   else
>     {
>       __space -= __diff;
>-      __ptr = static_cast<char*>(__ptr) + __diff;
>-      return __ptr;
>+      return __ptr = reinterpret_cast<void*>(__aligned);
>     }
> }
> 
>diff --git a/libstdc++-v3/testsuite/20_util/align/2.cc b/libstdc++-v3/testsuite/20_util/align/2.cc
>new file mode 100644
>index 0000000..efad56a
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/20_util/align/2.cc
>@@ -0,0 +1,42 @@
>+// { dg-options " -std=gnu++11 " }
>+
>+// Copyright (C) 2014 Free Software Foundation, Inc.
>+//
>+// This file is part of the GNU ISO C++ Library.  This library is free
>+// software; you can redistribute it and/or modify it under the terms
>+// of the GNU General Public License as published by the Free Software
>+// Foundation; either version 3, or (at your option) any later
>+// version.
>+
>+// This library is distributed in the hope that it will be useful, but
>+// WITHOUT ANY WARRANTY; without even the implied warranty of
>+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>+// General Public License for more details.
>+
>+// You should have received a copy of the GNU General Public License
>+// along with this library; see the file COPYING3.  If not see
>+// <http://www.gnu.org/licenses/>.
>+
>+// C++11 [ptr.align] (20.6.5): std::align
>+
>+#include <memory>
>+#include <testsuite_hooks.h>
>+
>+void
>+test01()
>+{
>+  bool test __attribute__((unused)) = true;
>+
>+  int i = 0;
>+  void* ptr = &i;
>+  auto space = sizeof(i);
>+  auto p2 = std::align(alignof(i), space, ptr, space);
>+  VERIFY( ptr == &i );
>+  VERIFY( p2 == &i );
>+  VERIFY(space == sizeof(i));
>+}
>+
>+int main()
>+{
>+  test01();
>+}
diff mbox

Patch

commit 60aa345d8122053f7c8ba7c743b458e799eb1455
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Oct 13 14:02:39 2014 +0100

    	PR libstdc++/57350
    	* include/std/memory (align): Do not adjust correctly aligned address.
    	* testsuite/20_util/align/2.cc: New.

diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index affc8b1..b5792ad 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -113,14 +113,15 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline void*
 align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
 {
-  const size_t __diff = __align - reinterpret_cast<uintptr_t>(__ptr) % __align;
-  if (__diff + __size >= __space)
+  const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
+  const auto __aligned = (__intptr - 1u + __align) & -__align;
+  const auto __diff = __aligned - __intptr;
+  if ((__size + __diff) > __space)
     return nullptr;
   else
     {
       __space -= __diff;
-      __ptr = static_cast<char*>(__ptr) + __diff;
-      return __ptr;
+      return __ptr = reinterpret_cast<void*>(__aligned);
     }
 }
 
diff --git a/libstdc++-v3/testsuite/20_util/align/2.cc b/libstdc++-v3/testsuite/20_util/align/2.cc
new file mode 100644
index 0000000..efad56a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/align/2.cc
@@ -0,0 +1,42 @@ 
+// { dg-options " -std=gnu++11 " }
+
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License as published by the Free Software
+// Foundation; either version 3, or (at your option) any later
+// version.
+
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// C++11 [ptr.align] (20.6.5): std::align
+
+#include <memory>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  int i = 0;
+  void* ptr = &i;
+  auto space = sizeof(i);
+  auto p2 = std::align(alignof(i), space, ptr, space);
+  VERIFY( ptr == &i );
+  VERIFY( p2 == &i );
+  VERIFY(space == sizeof(i));
+}
+
+int main()
+{
+  test01();
+}