================
@@ -15917,12 +15917,15 @@ struct PaddingCalculator {
const uint64_t DeclaredSizeInBits = Field->getBitWidthValue();
- // Handle over-sized bitfields:
- // unsigned char a : 12;
- // In this case, DeclaredSizeInBits is 12, but the actually occupied bit
- // size is 8, while the remaining 4 bits are padding.
+ // Oversized bit-fields (declared width larger than the field type) keep
+ // only the type's width as the value container. The extra declared bits
+ // are padding and follow that container (Itanium C++ ABI ยง2.4, II.1(b)).
+ // getIntWidth may be narrower still (bool, _BitInt); those occupied bits
+ // are the low-order bits of the value container.
+ const uint64_t ValueFieldBits =
+ std::min(DeclaredSizeInBits, Ctx.getTypeSize(Field->getType()));
const uint64_t OccupiedSizeInBits =
- std::min(DeclaredSizeInBits,
+ std::min(ValueFieldBits,
static_cast<uint64_t>(Ctx.getIntWidth(Field->getType())));
----------------
vhscampos wrote:
The code is wrong in the case of oversized bitfield of the `_BitInt` type. See
this example:
```c
struct S {
_BitInt(5) a : 6;
};
void foo(struct S *arg) {
__builtin_clear_padding(arg);
}
```
The clearing is lowered like this:
```asm
ldrb r1, [r0]
and r1, r1, #124
strb r1, [r0]
```
which still assumes that the padding is allocated before the occupied bits. I'd
expect the and to be done with `#248` (`1111 1000`).
https://github.com/llvm/llvm-project/pull/225494
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits