aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/new
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/new')
-rw-r--r--libcxx/include/new72
1 files changed, 53 insertions, 19 deletions
diff --git a/libcxx/include/new b/libcxx/include/new
index ed95caed1c41..0c826f4a061c 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -89,10 +89,12 @@ void operator delete[](void* ptr, void*) noexcept;
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
+#include <__type_traits/is_function.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/remove_cv.h>
#include <cstddef>
#include <cstdlib>
#include <exception>
-#include <type_traits>
#include <version>
#if defined(_LIBCPP_ABI_VCRUNTIME)
@@ -129,8 +131,8 @@ class _LIBCPP_EXCEPTION_ABI bad_alloc
{
public:
bad_alloc() _NOEXCEPT;
- virtual ~bad_alloc() _NOEXCEPT;
- virtual const char* what() const _NOEXCEPT;
+ ~bad_alloc() _NOEXCEPT override;
+ const char* what() const _NOEXCEPT override;
};
class _LIBCPP_EXCEPTION_ABI bad_array_new_length
@@ -138,15 +140,33 @@ class _LIBCPP_EXCEPTION_ABI bad_array_new_length
{
public:
bad_array_new_length() _NOEXCEPT;
- virtual ~bad_array_new_length() _NOEXCEPT;
- virtual const char* what() const _NOEXCEPT;
+ ~bad_array_new_length() _NOEXCEPT override;
+ const char* what() const _NOEXCEPT override;
};
typedef void (*new_handler)();
_LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT;
_LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT;
-#endif // !_LIBCPP_ABI_VCRUNTIME
+#elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME
+
+// When _HAS_EXCEPTIONS == 0, these complete definitions are needed,
+// since they would normally be provided in vcruntime_exception.h
+class bad_alloc : public exception {
+public:
+ bad_alloc() noexcept : exception("bad allocation") {}
+
+private:
+ friend class bad_array_new_length;
+
+ bad_alloc(char const* const __message) noexcept : exception(__message) {}
+};
+
+class bad_array_new_length : public bad_alloc {
+public:
+ bad_array_new_length() noexcept : bad_alloc("bad array new length") {}
+};
+#endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
@@ -277,9 +297,9 @@ _LIBCPP_INLINE_VISIBILITY
void __do_deallocate_handle_size(void *__ptr, size_t __size, _Args ...__args) {
#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
(void)__size;
- return __libcpp_operator_delete(__ptr, __args...);
+ return std::__libcpp_operator_delete(__ptr, __args...);
#else
- return __libcpp_operator_delete(__ptr, __size, __args...);
+ return std::__libcpp_operator_delete(__ptr, __size, __args...);
#endif
}
@@ -319,16 +339,26 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s
// chances are that you want to use `__libcpp_allocate` instead.
//
// Returns the allocated memory, or `nullptr` on failure.
-inline _LIBCPP_INLINE_VISIBILITY
-void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
-#if defined(_LIBCPP_MSVCRT_LIKE)
- return ::_aligned_malloc(__size, __alignment);
-#else
- void* __result = nullptr;
- (void)::posix_memalign(&__result, __alignment, __size);
- // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
- return __result;
-#endif
+inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) {
+# if defined(_LIBCPP_MSVCRT_LIKE)
+ return ::_aligned_malloc(__size, __alignment);
+# elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC)
+ // aligned_alloc() requires that __size is a multiple of __alignment,
+ // but for C++ [new.delete.general], only states "if the value of an
+ // alignment argument passed to any of these functions is not a valid
+ // alignment value, the behavior is undefined".
+ // To handle calls such as ::operator new(1, std::align_val_t(128)), we
+ // round __size up to the next multiple of __alignment.
+ size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1);
+ // Rounding up could have wrapped around to zero, so we have to add another
+ // max() ternary to the actual call site to avoid succeeded in that case.
+ return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size);
+# else
+ void* __result = nullptr;
+ (void)::posix_memalign(&__result, __alignment, __size);
+ // If posix_memalign fails, __result is unmodified so we still return `nullptr`.
+ return __result;
+# endif
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -347,7 +377,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
static_assert (!(is_function<_Tp>::value), "can't launder functions" );
- static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
+ static_assert (!(is_same<void, __remove_cv_t<_Tp> >::value), "can't launder cv-void" );
return __builtin_launder(__p);
}
@@ -373,4 +403,8 @@ inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUC
_LIBCPP_END_NAMESPACE_STD
+#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+# include <type_traits>
+#endif
+
#endif // _LIBCPP_NEW