From a248d8daf5d12795c2891c3ac8978b1f728e43e8 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 1 Jun 2022 07:50:46 +0200 Subject: [PATCH] Endian: Allow special bitfield union fields to cover the whole storage This requires a different computation of the mask since we can't shift out of the storage type. Change-Id: Ife85ca3e0c5ca47f06988a397cc2f8a7e28ad0fe Reviewed-by: Thiago Macieira --- src/corelib/global/qendian_p.h | 7 ++++++- tests/auto/corelib/global/qtendian/tst_qtendian.cpp | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qendian_p.h b/src/corelib/global/qendian_p.h index fd5a9dd992..9e31f7940a 100644 --- a/src/corelib/global/qendian_p.h +++ b/src/corelib/global/qendian_p.h @@ -139,7 +139,12 @@ public: static constexpr UnsignedType mask() noexcept { - return ((UnsignedType(1) << width) - 1) << pos; + if constexpr (width == sizeof(UnsignedType) * 8) { + static_assert(pos == 0); + return ~UnsignedType(0); + } else { + return ((UnsignedType(1) << width) - 1) << pos; + } } private: diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp index 7f13559067..e688768b74 100644 --- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp +++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp @@ -377,8 +377,9 @@ void testBitfieldUnion() using upper = Member<21, 11, uint>; using lower = Member<10, 11, uint>; using bottom = Member<0, 10, int>; + using all = Member<0, 32, uint>; - using UnionType = Union; + using UnionType = Union; UnionType u; u.template set(200); @@ -402,6 +403,15 @@ void testBitfieldUnion() UnionType u2(QSpecialIntegerBitfieldZero); QCOMPARE(u2.data(), 0U); + u2.template set(std::numeric_limits::max()); + QCOMPARE(u2.template get(), std::numeric_limits::max()); + + u2.template set(453); + QCOMPARE(u2.template get(), 453U); + + u2.template set(0); + QCOMPARE(u2.template get(), 0U); + UnionType u3(42U); QCOMPARE(u3.data(), 42U);