AddPadding: Always pad bitfields with "int8_t"s

The underlying type of bitfield is important to the size of a struct:

  struct Foo { int64_t bitfield : 1; };
  struct Bar { int8_t bitfield : 1; };

  sizeof(Foo) = 8;
  sizeof(Bar) = 1;
This commit is contained in:
Alastair Robertson 2023-07-19 08:12:45 -07:00 committed by Alastair Robertson
parent 325837c61b
commit 04ce7446b2
2 changed files with 25 additions and 14 deletions

View File

@ -130,16 +130,24 @@ void AddPadding::addPadding(uint64_t paddingStartBits,
if (paddingBits == 0)
return;
if (paddingBits % 8 == 0) {
// Pad with an array of bytes
// We must only use Int8s for padding in order to not accidentally increase
// the alignment requirements of this type. This applies to bitfield padding
// as well.
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
auto& paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8);
paddedMembers.emplace_back(paddingArray, MemberPrefix, paddingStartBits);
} else {
// Pad with a bitfield
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
if (paddingBits % 8 != 0) {
// Pad with a bitfield up to the next byte
paddedMembers.emplace_back(primitive, MemberPrefix, paddingStartBits,
paddingBits);
paddingBits % 8);
}
uint64_t paddingBytes = paddingBits / 8;
if (paddingBytes > 0) {
// Pad with an array of bytes
uint64_t paddingStartByte = (paddingStartBits + 7) / 8;
auto& paddingArray = typeGraph_.makeType<Array>(primitive, paddingBytes);
paddedMembers.emplace_back(paddingArray, MemberPrefix,
paddingStartByte * 8);
}
}

View File

@ -124,20 +124,23 @@ TEST(AddPaddingTest, Bitfields) {
Member: b2 (offset: 0.375, bitsize: 2)
Primitive: int8_t
Member: __oi_padding (offset: 0.625, bitsize: 3)
Primitive: int64_t
Primitive: int8_t
Member: b3 (offset: 1, bitsize: 1)
Primitive: int8_t
Member: __oi_padding (offset: 1.125, bitsize: 55)
Primitive: int64_t
Member: __oi_padding (offset: 1.125, bitsize: 7)
Primitive: int8_t
Member: __oi_padding (offset: 2)
[1] Array: (length: 6)
Primitive: int8_t
Member: b4 (offset: 8, bitsize: 24)
Primitive: int64_t
Member: __oi_padding (offset: 11)
[1] Array: (length: 1)
[2] Array: (length: 1)
Primitive: int8_t
Member: n (offset: 12)
Primitive: int16_t
Member: __oi_padding (offset: 14)
[2] Array: (length: 2)
[3] Array: (length: 2)
Primitive: int8_t
)");
}