[libc++] Clean up logic around aligned/sized allocation and deallocation
Due to the need to support compilers that implement builtin operator
new/delete but not their align_val_t overloaded versions, there was a
lot of complexity. By assuming that a compiler that supports the builtin
new/delete operators also supports their align_val_t overloads, the code
can be simplified quite a bit.
Differential Revision: https://reviews.llvm.org/D88301
GitOrigin-RevId: c778f6c4f9d511023c0d71b9e14a90e60445d314
diff --git a/include/__config b/include/__config
index b512611..8d2ab2e 100644
--- a/include/__config
+++ b/include/__config
@@ -868,10 +868,6 @@
# define _LIBCPP_EXPLICIT
#endif
-#if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete)
-#define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
-#endif
-
#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx
# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \
diff --git a/include/new b/include/new
index dbfdab9..e21c22b 100644
--- a/include/new
+++ b/include/new
@@ -117,11 +117,6 @@
# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
#endif
-#if !__has_builtin(__builtin_operator_new) || \
- __has_builtin(__builtin_operator_new) < 201802L
-#define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
-#endif
-
namespace std // purposefully not using versioning namespace
{
@@ -234,80 +229,54 @@
#endif
}
+template <class ..._Args>
+_LIBCPP_INLINE_VISIBILITY
+void* __libcpp_operator_new(_Args ...__args) {
+#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
+ return __builtin_operator_new(__args...);
+#else
+ return ::operator new(__args...);
+#endif
+}
+
+template <class ..._Args>
+_LIBCPP_INLINE_VISIBILITY
+void __libcpp_operator_delete(_Args ...__args) {
+#if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete)
+ __builtin_operator_delete(__args...);
+#else
+ ::operator delete(__args...);
+#endif
+}
+
inline _LIBCPP_INLINE_VISIBILITY
void *__libcpp_allocate(size_t __size, size_t __align) {
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
if (__is_overaligned_for_new(__align)) {
const align_val_t __align_val = static_cast<align_val_t>(__align);
-# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
- return ::operator new(__size, __align_val);
-# else
- return __builtin_operator_new(__size, __align_val);
-# endif
+ return __libcpp_operator_new(__size, __align_val);
}
-#else
- ((void)__align);
#endif
-#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
- return ::operator new(__size);
+
+ (void)__align;
+ return __libcpp_operator_new(__size);
+}
+
+template <class ..._Args>
+_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...);
#else
- return __builtin_operator_new(__size);
+ return __libcpp_operator_delete(__ptr, __size, __args...);
#endif
}
-struct _DeallocateCaller {
- template <class _A1, class _A2>
- static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) {
-#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
- defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
- return ::operator delete(__ptr, __a1, __a2);
-#else
- return __builtin_operator_delete(__ptr, __a1, __a2);
-#endif
- }
-
- template <class _A1>
- static inline void __do_call(void *__ptr, _A1 __a1) {
-#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \
- defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE)
- return ::operator delete(__ptr, __a1);
-#else
- return __builtin_operator_delete(__ptr, __a1);
-#endif
- }
-
- static inline void __do_call(void *__ptr) {
-#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
- return ::operator delete(__ptr);
-#else
- return __builtin_operator_delete(__ptr);
-#endif
- }
-
- static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) {
-#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
- ((void)__size);
- return __do_call(__ptr);
-#else
- return __do_call(__ptr, __size);
-#endif
- }
-
-#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
- static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) {
-#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
- ((void)__size);
- return __do_call(__ptr, __align);
-#else
- return __do_call(__ptr, __size, __align);
-#endif
- }
-#endif
-
- static inline _LIBCPP_INLINE_VISIBILITY
- void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) {
+inline _LIBCPP_INLINE_VISIBILITY
+void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
- ((void)__align);
+ (void)__align;
return __do_deallocate_handle_size(__ptr, __size);
#else
if (__is_overaligned_for_new(__align)) {
@@ -317,31 +286,20 @@
return __do_deallocate_handle_size(__ptr, __size);
}
#endif
- }
-
- static inline _LIBCPP_INLINE_VISIBILITY
- void __do_deallocate_handle_align(void *__ptr, size_t __align) {
-#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
- ((void)__align);
- return __do_call(__ptr);
-#else
- if (__is_overaligned_for_new(__align)) {
- const align_val_t __align_val = static_cast<align_val_t>(__align);
- return __do_call(__ptr, __align_val);
- } else {
- return __do_call(__ptr);
- }
-#endif
- }
-};
-
-inline _LIBCPP_INLINE_VISIBILITY
-void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) {
- _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align);
}
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) {
- _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align);
+#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
+ (void)__align;
+ return __libcpp_operator_delete(__ptr);
+#else
+ if (__is_overaligned_for_new(__align)) {
+ const align_val_t __align_val = static_cast<align_val_t>(__align);
+ return __libcpp_operator_delete(__ptr, __align_val);
+ } else {
+ return __libcpp_operator_delete(__ptr);
+ }
+#endif
}
template <class _Tp>