mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 20:29:39 +08:00
This reverts commit r306310. r306310 causes clang to reject a call to an aligned allocation or deallocation function if it is not implemented in the standard library of the deployment target. This is not the desired behavior when users have defined their own aligned functions. rdar://problem/32664169 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@306859 91177308-0d34-0410-b5e6-96231b3b80d8
256 lines
9.4 KiB
C++
256 lines
9.4 KiB
C++
// -*- C++ -*-
|
|
//===----------------------------- new ------------------------------------===//
|
|
//
|
|
// 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP_NEW
|
|
#define _LIBCPP_NEW
|
|
|
|
/*
|
|
new synopsis
|
|
|
|
namespace std
|
|
{
|
|
|
|
class bad_alloc
|
|
: public exception
|
|
{
|
|
public:
|
|
bad_alloc() noexcept;
|
|
bad_alloc(const bad_alloc&) noexcept;
|
|
bad_alloc& operator=(const bad_alloc&) noexcept;
|
|
virtual const char* what() const noexcept;
|
|
};
|
|
|
|
class bad_array_length : public bad_alloc // FIXME: Not part of C++
|
|
{
|
|
public:
|
|
bad_array_length() noexcept;
|
|
};
|
|
|
|
class bad_array_new_length : public bad_alloc // C++14
|
|
{
|
|
public:
|
|
bad_array_new_length() noexcept;
|
|
};
|
|
|
|
enum class align_val_t : size_t {}; // C++17
|
|
struct nothrow_t {};
|
|
extern const nothrow_t nothrow;
|
|
typedef void (*new_handler)();
|
|
new_handler set_new_handler(new_handler new_p) noexcept;
|
|
new_handler get_new_handler() noexcept;
|
|
|
|
} // std
|
|
|
|
void* operator new(std::size_t size); // replaceable
|
|
void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17
|
|
void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable
|
|
void* operator new(std::size_t size, std::align_val_t alignment,
|
|
const std::nothrow_t&) noexcept; // replaceable, C++17
|
|
void operator delete(void* ptr) noexcept; // replaceable
|
|
void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14
|
|
void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17
|
|
void operator delete(void* ptr, std::size_t size,
|
|
std::align_val_t alignment) noexcept; // replaceable, C++17
|
|
void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable
|
|
void operator delete(void* ptr, std:align_val_t alignment,
|
|
const std::nothrow_t&) noexcept; // replaceable, C++17
|
|
|
|
void* operator new[](std::size_t size); // replaceable
|
|
void* operator new[](std::size_t size,
|
|
std::align_val_t alignment) noexcept; // replaceable, C++17
|
|
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
|
|
void* operator new[](std::size_t size, std::align_val_t alignment,
|
|
const std::nothrow_t&) noexcept; // replaceable, C++17
|
|
void operator delete[](void* ptr) noexcept; // replaceable
|
|
void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14
|
|
void operator delete[](void* ptr,
|
|
std::align_val_t alignment) noexcept; // replaceable, C++17
|
|
void operator delete[](void* ptr, std::size_t size,
|
|
std::align_val_t alignment) noexcept; // replaceable, C++17
|
|
void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable
|
|
void operator delete[](void* ptr, std::align_val_t alignment,
|
|
const std::nothrow_t&) noexcept; // replaceable, C++17
|
|
|
|
void* operator new (std::size_t size, void* ptr) noexcept;
|
|
void* operator new[](std::size_t size, void* ptr) noexcept;
|
|
void operator delete (void* ptr, void*) noexcept;
|
|
void operator delete[](void* ptr, void*) noexcept;
|
|
|
|
*/
|
|
|
|
#include <__config>
|
|
#include <exception>
|
|
#include <cstddef>
|
|
#ifdef _LIBCPP_NO_EXCEPTIONS
|
|
#include <cstdlib>
|
|
#endif
|
|
|
|
#if defined(_LIBCPP_ABI_MICROSOFT)
|
|
#include <new.h>
|
|
#endif
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
#pragma GCC system_header
|
|
#endif
|
|
|
|
#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
|
|
(defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
|
|
# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
|
|
#endif
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \
|
|
(!(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
|
|
(defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)))
|
|
# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
|
|
#endif
|
|
|
|
namespace std // purposefully not using versioning namespace
|
|
{
|
|
|
|
#if !defined(_LIBCPP_ABI_MICROSOFT)
|
|
struct _LIBCPP_TYPE_VIS nothrow_t {};
|
|
extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
|
|
|
|
class _LIBCPP_EXCEPTION_ABI bad_alloc
|
|
: public exception
|
|
{
|
|
public:
|
|
bad_alloc() _NOEXCEPT;
|
|
virtual ~bad_alloc() _NOEXCEPT;
|
|
virtual const char* what() const _NOEXCEPT;
|
|
};
|
|
|
|
class _LIBCPP_EXCEPTION_ABI bad_array_new_length
|
|
: public bad_alloc
|
|
{
|
|
public:
|
|
bad_array_new_length() _NOEXCEPT;
|
|
virtual ~bad_array_new_length() _NOEXCEPT;
|
|
virtual const char* what() const _NOEXCEPT;
|
|
};
|
|
|
|
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_MICROSOFT
|
|
|
|
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
|
|
|
|
#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
|
|
|
|
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
|
|
bad_array_length : public bad_alloc {
|
|
public:
|
|
bad_array_length() _NOEXCEPT;
|
|
virtual ~bad_array_length() _NOEXCEPT;
|
|
virtual const char* what() const _NOEXCEPT;
|
|
};
|
|
|
|
#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
|
|
|
|
#endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
|
|
#else
|
|
enum align_val_t { __zero = 0, __max = (size_t)-1 };
|
|
#endif
|
|
#endif
|
|
|
|
} // std
|
|
|
|
#if defined(_LIBCPP_CXX03_LANG)
|
|
#define _THROW_BAD_ALLOC throw(std::bad_alloc)
|
|
#else
|
|
#define _THROW_BAD_ALLOC
|
|
#endif
|
|
|
|
#if !defined(_LIBCPP_ABI_MICROSOFT)
|
|
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
|
|
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
|
|
#endif
|
|
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
|
|
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
|
|
#endif
|
|
|
|
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
|
|
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
|
|
#endif
|
|
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
|
|
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
|
|
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
|
|
#endif
|
|
#endif
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;}
|
|
inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
|
|
inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {}
|
|
inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {}
|
|
|
|
#endif // !_LIBCPP_ABI_MICROSOFT
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY void *__allocate(size_t __size) {
|
|
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
|
|
return ::operator new(__size);
|
|
#else
|
|
return __builtin_operator_new(__size);
|
|
#endif
|
|
}
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void *__ptr) {
|
|
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
|
|
::operator delete(__ptr);
|
|
#else
|
|
__builtin_operator_delete(__ptr);
|
|
#endif
|
|
}
|
|
|
|
#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
|
|
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
|
|
#endif
|
|
void __throw_bad_array_length()
|
|
{
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
throw bad_array_length();
|
|
#else
|
|
_VSTD::abort();
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
#endif // _LIBCPP_NEW
|