Index: include/memory =================================================================== --- include/memory +++ include/memory @@ -2004,7 +2004,38 @@ __n = __m; while (__n > 0) { +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) +#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) + if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__) +#else + if (std::alignment_of<_Tp>::value > + std::alignment_of::value) +#endif + { + std::align_val_t __al = + std::align_val_t(std::alignment_of<_Tp>::value); + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), __al, nothrow)); + } else { + __r.first = static_cast<_Tp*>(::operator new( + __n * sizeof(_Tp), nothrow)); + } +#else +#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) + if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__) +#else + if (std::alignment_of<_Tp>::value > + std::alignment_of::value) +#endif + { + // Since aligned operator new is unavailable, return an empty + // buffer rather than one with invalid alignment. + return __r; + } + __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow)); +#endif + if (__r.first) { __r.second = __n; @@ -2017,7 +2048,23 @@ template inline _LIBCPP_INLINE_VISIBILITY -void return_temporary_buffer(_Tp* __p) _NOEXCEPT {::operator delete(__p);} +void return_temporary_buffer(_Tp* __p) _NOEXCEPT +{ +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) +#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) + if (std::alignment_of<_Tp>::value > __STDCPP_DEFAULT_NEW_ALIGNMENT__) +#else + if (std::alignment_of<_Tp>::value > + std::alignment_of::value) +#endif + { + std::align_val_t __al = std::align_val_t(std::alignment_of<_Tp>::value); + ::operator delete(__p, __al); + return; + } +#endif + ::operator delete(__p); +} #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) template Index: test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp =================================================================== --- test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp +++ test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// pair +// get_temporary_buffer(ptrdiff_t n); +// +// template +// void +// return_temporary_buffer(T* p); + +#include +#include + +struct alignas(32) A { + int field; +}; + +int main() +{ + std::pair ip = std::get_temporary_buffer(5); + assert(!(ip.first == nullptr) ^ (ip.second == 0)); + assert(reinterpret_cast(ip.first) % alignof(A) == 0); + std::return_temporary_buffer(ip.first); +}