[libc++] Make __has_array_cookie a variable template (#212767)
Using variable templates is slightly faster to compile and more readable, so we might as well use them.
This commit is contained in:
parent
5aec353bd6
commit
090b6569b6
3 changed files with 9 additions and 11 deletions
|
|
@ -14,9 +14,7 @@
|
|||
#include <__configuration/abi.h>
|
||||
#include <__cstddef/size_t.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
#include <__type_traits/is_trivially_destructible.h>
|
||||
#include <__type_traits/negation.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
|
|
@ -37,10 +35,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
// TODO: We should factor in the choice of the usual deallocation function in this determination:
|
||||
// a cookie may be available in more cases but we ignore those for now.
|
||||
template <class _Tp>
|
||||
struct __has_array_cookie : _Not<is_trivially_destructible<_Tp> > {};
|
||||
inline const bool __has_array_cookie_v = !is_trivially_destructible<_Tp>::value;
|
||||
#else
|
||||
template <class _Tp>
|
||||
struct __has_array_cookie : false_type {};
|
||||
inline const bool __has_array_cookie_v = false;
|
||||
#endif
|
||||
|
||||
struct __itanium_array_cookie {
|
||||
|
|
@ -97,7 +95,7 @@ template <class _Tp>
|
|||
// Avoid failures when -fsanitize-address-poison-custom-array-cookie is enabled
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") size_t __get_array_cookie([[__maybe_unused__]] _Tp const* __ptr) {
|
||||
static_assert(
|
||||
__has_array_cookie<_Tp>::value, "Trying to access the array cookie of a type that is not guaranteed to have one");
|
||||
__has_array_cookie_v<_Tp>, "Trying to access the array cookie of a type that is not guaranteed to have one");
|
||||
|
||||
#if defined(_LIBCPP_ABI_ITANIUM)
|
||||
using _ArrayCookie = __itanium_array_cookie;
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ struct __unique_ptr_array_bounds_stateless {
|
|||
|
||||
template <class _Deleter,
|
||||
class _Tp,
|
||||
__enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>
|
||||
__enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
|
||||
// In constant expressions, we can't check the array cookie so we just pretend that the index
|
||||
// is in-bounds. The compiler catches invalid accesses anyway.
|
||||
|
|
@ -331,7 +331,7 @@ struct __unique_ptr_array_bounds_stateless {
|
|||
|
||||
template <class _Deleter,
|
||||
class _Tp,
|
||||
__enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>
|
||||
__enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t) const {
|
||||
return true; // If we don't have an array cookie, we assume the access is in-bounds
|
||||
}
|
||||
|
|
@ -349,7 +349,7 @@ struct __unique_ptr_array_bounds_stored {
|
|||
// Use the array cookie if there's one
|
||||
template <class _Deleter,
|
||||
class _Tp,
|
||||
__enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>
|
||||
__enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
|
||||
if (__libcpp_is_constant_evaluated())
|
||||
return true;
|
||||
|
|
@ -360,7 +360,7 @@ struct __unique_ptr_array_bounds_stored {
|
|||
// Otherwise, fall back on the stored size (if any)
|
||||
template <class _Deleter,
|
||||
class _Tp,
|
||||
__enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>
|
||||
__enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie_v<_Tp>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t __index) const {
|
||||
return __index < __size_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ struct MyDeleter {
|
|||
|
||||
template <class WithCookie, class NoCookie>
|
||||
void test() {
|
||||
LIBCPP_STATIC_ASSERT(std::__has_array_cookie<WithCookie>::value);
|
||||
LIBCPP_STATIC_ASSERT(!std::__has_array_cookie<NoCookie>::value);
|
||||
LIBCPP_STATIC_ASSERT(std::__has_array_cookie_v<WithCookie>);
|
||||
LIBCPP_STATIC_ASSERT(!std::__has_array_cookie_v<NoCookie>);
|
||||
|
||||
// For types with an array cookie, we can always detect OOB accesses. Note that reliance on an array
|
||||
// cookie is limited to the default deleter, since a unique_ptr with a custom deleter may not have
|
||||
|
|
|
|||
Loading…
Reference in a new issue