================
@@ -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())));
----------------
xiongzile 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:
> 
> ```assembly
>         ldrb    r1, [r0]
>         and     r1, r1, #124
>         strb    r1, [r0]
> ```
> 
> which still assumes that the padding is allocated before the occupied bits. 
> Remember that in BE the allocation is from MSB to LSB. I'd expect the and to 
> be done with `#248` (`1111 1000`).

But CodeGen currently stores the value in the low 5 bits of the 6-bit field, 
i.e. `01111100`, not `11111000`
Also GCC doesn't support `_BitInt(5) a: 6`, so I'm not sure which we should 
prefer...?


https://github.com/llvm/llvm-project/pull/225494
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to