Message ID | 20141013130408.GO4197@redhat.com |
---|---|
State | New |
Headers | show |
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(); >+}
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(); +}