[libc++] Fix constexpr dynamic allocation on GCC 10
We're technically not allowed by the Standard to call ::operator new in
constexpr functions like __libcpp_allocate. Clang doesn't seem to complain
about it, but GCC does.
Cr-Mirrored-From: https://chromium.googlesource.com/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: d092c912885cc152bef27019525b8fd0761aaaa2
diff --git a/include/memory b/include/memory
index 112ee9d..67a6ddd 100644
--- a/include/memory
+++ b/include/memory
@@ -1678,12 +1678,20 @@
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ if (__libcpp_is_constant_evaluated()) {
+ return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
+ } else {
+ return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ }
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
- _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ if (__libcpp_is_constant_evaluated()) {
+ ::operator delete(__p);
+ } else {
+ _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ }
}
// C++20 Removed members
@@ -1751,12 +1759,20 @@
if (__n > allocator_traits<allocator>::max_size(*this))
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
- return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ if (__libcpp_is_constant_evaluated()) {
+ return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
+ } else {
+ return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
+ }
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void deallocate(const _Tp* __p, size_t __n) {
- _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ if (__libcpp_is_constant_evaluated()) {
+ ::operator delete(const_cast<_Tp*>(__p));
+ } else {
+ _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
+ }
}
// C++20 Removed members