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) if (paddingBits == 0)
return; return;
if (paddingBits % 8 == 0) { // We must only use Int8s for padding in order to not accidentally increase
// Pad with an array of bytes // the alignment requirements of this type. This applies to bitfield padding
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8); // as well.
auto& paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8); auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
paddedMembers.emplace_back(paddingArray, MemberPrefix, paddingStartBits);
} else { if (paddingBits % 8 != 0) {
// Pad with a bitfield // Pad with a bitfield up to the next byte
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
paddedMembers.emplace_back(primitive, MemberPrefix, paddingStartBits, 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) Member: b2 (offset: 0.375, bitsize: 2)
Primitive: int8_t Primitive: int8_t
Member: __oi_padding (offset: 0.625, bitsize: 3) Member: __oi_padding (offset: 0.625, bitsize: 3)
Primitive: int64_t Primitive: int8_t
Member: b3 (offset: 1, bitsize: 1) Member: b3 (offset: 1, bitsize: 1)
Primitive: int8_t Primitive: int8_t
Member: __oi_padding (offset: 1.125, bitsize: 55) Member: __oi_padding (offset: 1.125, bitsize: 7)
Primitive: int64_t Primitive: int8_t
Member: __oi_padding (offset: 2)
[1] Array: (length: 6)
Primitive: int8_t
Member: b4 (offset: 8, bitsize: 24) Member: b4 (offset: 8, bitsize: 24)
Primitive: int64_t Primitive: int64_t
Member: __oi_padding (offset: 11) Member: __oi_padding (offset: 11)
[1] Array: (length: 1) [2] Array: (length: 1)
Primitive: int8_t Primitive: int8_t
Member: n (offset: 12) Member: n (offset: 12)
Primitive: int16_t Primitive: int16_t
Member: __oi_padding (offset: 14) Member: __oi_padding (offset: 14)
[2] Array: (length: 2) [3] Array: (length: 2)
Primitive: int8_t Primitive: int8_t
)"); )");
} }