summaryrefslogtreecommitdiffstats
path: root/libcxx/include/memory
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-03-22 04:42:56 +0000
committerEric Fiselier <eric@efcs.ca>2018-03-22 04:42:56 +0000
commitf2918d1c24c9e69f1c63a4ca864bbd68ef5a51cc (patch)
treea3e112d71ad60d20340cfbf634b0da3a882d6ff7 /libcxx/include/memory
parentfc179c6dd59b0da8068ecb800095e79d2ec41bc6 (diff)
downloadbcm5719-llvm-f2918d1c24c9e69f1c63a4ca864bbd68ef5a51cc.tar.gz
bcm5719-llvm-f2918d1c24c9e69f1c63a4ca864bbd68ef5a51cc.zip
Fix PR22634 - std::allocator doesn't respect over-aligned types.
This patch fixes std::allocator, and more specifically, all users of __libcpp_allocate and __libcpp_deallocate, to support over-aligned types. __libcpp_allocate/deallocate now take an alignment parameter, and when the specified alignment is greater than that supported by malloc/new, the aligned version of operator new is called (assuming it's available). When aligned new isn't available, the old behavior has been kept, and the alignment parameter is ignored. This patch depends on recent changes to __builtin_operator_new/delete which allow them to be used to call any regular new/delete operator. By using __builtin_operator_new/delete when possible, the new/delete erasure optimization is maintained. llvm-svn: 328180
Diffstat (limited to 'libcxx/include/memory')
-rw-r--r--libcxx/include/memory37
1 files changed, 7 insertions, 30 deletions
diff --git a/libcxx/include/memory b/libcxx/include/memory
index ea52ba2cb64..021bd136af4 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -1796,10 +1796,10 @@ public:
if (__n > max_size())
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*)__p);}
+ {_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -1897,10 +1897,10 @@ public:
if (__n > max_size())
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
+ return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
- {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p));}
+ {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __alignof(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@@ -2016,12 +2016,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
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<std::max_align_t>::value)
-#endif
+ if (__is_overaligned_for_new(__alignof(_Tp)))
{
std::align_val_t __al =
std::align_val_t(std::alignment_of<_Tp>::value);
@@ -2032,12 +2027,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
__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<std::max_align_t>::value)
-#endif
+ if (__is_overaligned_for_new(__alignof(_Tp)))
{
// Since aligned operator new is unavailable, return an empty
// buffer rather than one with invalid alignment.
@@ -2061,20 +2051,7 @@ template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
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<std::max_align_t>::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);
+ _VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));
}
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
OpenPOWER on IntegriCloud