From 9068e2071cd6983f04732947a5cef4926a84c531 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 16 Jan 2020 04:09:11 -0800 Subject: [PATCH] offsetof: proper detection when sizeof() != alignof --- .../vapours/util/util_parent_of_member.hpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp b/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp index 8de42b9a4..14c7a3499 100644 --- a/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp +++ b/libraries/libvapours/include/vapours/util/util_parent_of_member.hpp @@ -22,14 +22,15 @@ namespace ams::util { namespace impl { - template + template struct OffsetOfUnionHolder { template union UnionImpl { + using PaddingMember = std::array; static constexpr size_t GetOffset() { return Offset; } struct { - char padding[Offset]; + PaddingMember padding[Offset]; MemberType members[(sizeof(ParentType) / sizeof(MemberType)) + 1]; } data; UnionImpl next_union; @@ -46,12 +47,12 @@ namespace ams::util { }; template - union UnionImpl { /* Empty */ }; + union UnionImpl { /* Empty */ }; }; template struct OffsetOfCalculator { - using UnionHolder = typename OffsetOfUnionHolder::template UnionImpl; + using UnionHolder = typename OffsetOfUnionHolder::template UnionImpl; union Union { char c; UnionHolder first_union; @@ -80,15 +81,15 @@ namespace ams::util { const auto start = std::addressof(cur_union.data.members[0]); const auto next = GetNextAddress(start, target); - if (next < target) { - if constexpr (Offset + 1 < alignof(MemberType)) { + if (next != target) { + if constexpr (Offset < sizeof(MemberType) / alignof(MemberType)) { return OffsetOfImpl(member, cur_union.next_union); } else { - static_assert(Offset + 1 <= alignof(MemberType)); + std::abort(); } } - return (next - start) * sizeof(MemberType) + Offset; + return (next - start) * sizeof(MemberType) + Offset * alignof(MemberType); }