diff --git a/AK/IntrusiveList.h b/AK/IntrusiveList.h index 9475efd4923..b671a7a11c0 100644 --- a/AK/IntrusiveList.h +++ b/AK/IntrusiveList.h @@ -375,13 +375,20 @@ inline typename IntrusiveList::ConstIterator IntrusiveList template T::*member> inline T* IntrusiveList::node_to_value(SubstitutedIntrusiveListNode& node) { + // Note: A data member pointer is a 32-bit offset in the Windows ABI (both x86 and x86_64), + // whereas it is an appropriately sized ptrdiff_t in the Itanium ABI, the following ensures + // that we always use the correct type for the subtraction. + using EquivalentNumericTypeForDataMemberPointer = Conditional; + static_assert(sizeof(EquivalentNumericTypeForDataMemberPointer) == sizeof(member), + "The equivalent numeric type for the data member pointer must have the same size as the data member pointer itself."); + // Note: Since this might seem odd, here's an explanation on what this function actually does: // `node` is a reference that resides in some part of the actual value (of type T), the // placement (i.e. offset) of which is described by the pointer-to-data-member parameter // named `member`. // This function effectively takes in the address of the data member, and returns the address // of the value (of type T) holding that member. - return bit_cast(bit_cast(&node) - bit_cast(member)); + return bit_cast(bit_cast(&node) - bit_cast(member)); } template