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 <thiago.macieira@intel.com>
This commit is contained in:
Ulf Hermann 2022-06-01 07:50:46 +02:00
parent b9cce12e76
commit a248d8daf5
2 changed files with 17 additions and 2 deletions

View File

@ -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:

View File

@ -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<upper, lower, bottom>;
using UnionType = Union<upper, lower, bottom, all>;
UnionType u;
u.template set<upper>(200);
@ -402,6 +403,15 @@ void testBitfieldUnion()
UnionType u2(QSpecialIntegerBitfieldZero);
QCOMPARE(u2.data(), 0U);
u2.template set<all>(std::numeric_limits<uint>::max());
QCOMPARE(u2.template get<all>(), std::numeric_limits<uint>::max());
u2.template set<all>(453);
QCOMPARE(u2.template get<all>(), 453U);
u2.template set<all>(0);
QCOMPARE(u2.template get<all>(), 0U);
UnionType u3(42U);
QCOMPARE(u3.data(), 42U);