Skip to content

Commit 69e8b8f

Browse files
committed
More fixes
1 parent 563aef6 commit 69e8b8f

File tree

1 file changed

+27
-21
lines changed

1 file changed

+27
-21
lines changed

libcxx/include/__memory/array_cookie.h

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,21 +42,38 @@ template <class _Tp>
4242
struct __has_array_cookie : false_type {};
4343
#endif
4444

45-
// Return the array cookie located before the given pointer.
45+
template <class _Tp, bool _HasPadding = (_LIBCPP_PREFERRED_ALIGNOF(_Tp) > sizeof(size_t))>
46+
struct [[__gnu__::__aligned__(_LIBCPP_PREFERRED_ALIGNOF(_Tp))]] __itanium_array_cookie {
47+
size_t __element_count;
48+
};
49+
50+
template <class _Tp>
51+
struct [[__gnu__::__aligned__(_LIBCPP_PREFERRED_ALIGNOF(_Tp))]] __itanium_array_cookie<_Tp, /* _HasPadding */ true> {
52+
char __padding[_LIBCPP_PREFERRED_ALIGNOF(_Tp) - sizeof(size_t)];
53+
size_t __element_count;
54+
};
55+
56+
template <class _Tp>
57+
struct [[__gnu__::__aligned__(_LIBCPP_ALIGNOF(_Tp))]] __arm_array_cookie {
58+
size_t __element_size;
59+
size_t __element_count;
60+
};
61+
62+
// Return the element count in the array cookie located before the given pointer.
4663
//
4764
// In the Itanium ABI [1]
4865
// ----------------------
49-
// The array cookie is stored immediately before the first element of the array. If the preferred alignment
66+
// The element count is stored immediately before the first element of the array. If the preferred alignment
5067
// of array elements (which is different from the ABI alignment) is more than that of size_t, additional
51-
// padding bytes exist before the array cookie. Assuming array elements of size and alignment 16 bytes, that
52-
// gives us the following layout:
68+
// padding bytes exist at the beginning of the array cookie. Assuming array elements of size and alignment 16
69+
// bytes, that gives us the following layout:
5370
//
5471
// |ooooooooxxxxxxxxaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd|
5572
// ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5673
// | ^^^^^^^^ |
5774
// | | array elements
5875
// padding |
59-
// array cookie
76+
// element count
6077
//
6178
// In practice, it is sufficient to read the bytes immediately before the first array element.
6279
//
@@ -78,8 +95,8 @@ struct __has_array_cookie : false_type {};
7895
// element size | padding |
7996
// element count array elements
8097
//
81-
// We calculate the starting address of the allocation by taking into account the ABI (not the preferred)
82-
// alignment of the type.
98+
// We calculate the starting address of the allocation by taking into account the ABI alignment (not
99+
// the preferred alignment) of the type.
83100
//
84101
// [1]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies
85102
// [2]: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-C++-differences
@@ -90,22 +107,11 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") size_t __get_array_cookie([
90107
__has_array_cookie<_Tp>::value, "Trying to access the array cookie of a type that is not guaranteed to have one");
91108

92109
#if defined(_LIBCPP_ABI_ITANIUM)
93-
94-
struct _ArrayCookie {
95-
size_t __element_count;
96-
};
97-
110+
using _ArrayCookie = __itanium_array_cookie<_Tp>;
98111
#elif defined(_LIBCPP_ABI_ITANIUM_WITH_ARM_DIFFERENCES)
99-
100-
struct [[__gnu__::__aligned__(_LIBCPP_ALIGNOF(_Tp))]] _ArrayCookie {
101-
size_t __element_size;
102-
size_t __element_count;
103-
};
104-
112+
using _ArrayCookie = __arm_array_cookie<_Tp>;
105113
#else
106-
107-
static_assert(false, "Getting the array cookie is not implemented on this ABI");
108-
114+
static_assert(false, "The array cookie layout is unknown on this ABI");
109115
#endif
110116

111117
char const* __allocation_start = reinterpret_cast<char const*>(__ptr) - sizeof(_ArrayCookie);

0 commit comments

Comments
 (0)