@@ -43,14 +43,7 @@ template <class _Tp>
4343struct __has_array_cookie : false_type {};
4444#endif
4545
46- template <class _Tp , bool _HasPadding = (_LIBCPP_PREFERRED_ALIGNOF(_Tp) > sizeof (size_t ))>
47- struct [[__gnu__::__aligned__(_LIBCPP_PREFERRED_ALIGNOF(_Tp))]] __itanium_array_cookie {
48- size_t __element_count;
49- };
50-
51- template <class _Tp >
52- struct [[__gnu__::__aligned__(_LIBCPP_PREFERRED_ALIGNOF(_Tp))]] __itanium_array_cookie<_Tp, /* _HasPadding */ true > {
53- char __padding[_LIBCPP_PREFERRED_ALIGNOF (_Tp) - sizeof (size_t )];
46+ struct __itanium_array_cookie {
5447 size_t __element_count;
5548};
5649
@@ -66,8 +59,8 @@ struct [[__gnu__::__aligned__(_LIBCPP_ALIGNOF(_Tp))]] __arm_array_cookie {
6659// ----------------------
6760// The element count is stored immediately before the first element of the array. If the preferred alignment
6861// of array elements (which is different from the ABI alignment) is more than that of size_t, additional
69- // padding bytes exist at the beginning of the array cookie. Assuming array elements of size and alignment 16
70- // bytes, that gives us the following layout:
62+ // padding bytes exist before the array cookie. Assuming array elements of size and alignment 16 bytes, that
63+ // gives us the following layout:
7164//
7265// |ooooooooxxxxxxxxaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd|
7366// ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -76,8 +69,6 @@ struct [[__gnu__::__aligned__(_LIBCPP_ALIGNOF(_Tp))]] __arm_array_cookie {
7669// padding |
7770// element count
7871//
79- // In practice, it is sufficient to read the bytes immediately before the first array element.
80- //
8172//
8273// In the Itanium ABI with ARM differences [2]
8374// -------------------------------------------
@@ -96,8 +87,9 @@ struct [[__gnu__::__aligned__(_LIBCPP_ALIGNOF(_Tp))]] __arm_array_cookie {
9687// element size | padding |
9788// element count array elements
9889//
99- // We calculate the starting address of the allocation by taking into account the ABI alignment (not
100- // the preferred alignment) of the type.
90+ // We must be careful to take into account the alignment of the array cookie, which may result in padding
91+ // bytes between the element count and the first element of the array. Note that for ARM, the compiler
92+ // aligns the array cookie using the ABI alignment, not the preferred alignment of array elements.
10193//
10294// [1]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies
10395// [2]: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Handle-C++-differences
@@ -118,11 +110,11 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") size_t __get_array_cookie([
118110 };
119111#endif
120112
121- char const * __allocation_start = reinterpret_cast <char const *>(__ptr) - sizeof (_ArrayCookie);
113+ char const * __array_cookie_start = reinterpret_cast <char const *>(__ptr) - sizeof (_ArrayCookie);
122114 _ArrayCookie __cookie;
123115 // This is necessary to avoid violating strict aliasing. It's valid because _ArrayCookie is an
124116 // implicit lifetime type.
125- __builtin_memcpy (std::addressof (__cookie), __allocation_start , sizeof (_ArrayCookie));
117+ __builtin_memcpy (std::addressof (__cookie), __array_cookie_start , sizeof (_ArrayCookie));
126118 return __cookie.__element_count ;
127119}
128120
0 commit comments