@@ -42,21 +42,38 @@ template <class _Tp>
4242struct __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