Author: Akram Hany
Date: 2026-02-23T10:01:11-05:00
New Revision: 222e661c89cfbfd8a6b55e4cd1d0925182655c9d

URL: 
https://github.com/llvm/llvm-project/commit/222e661c89cfbfd8a6b55e4cd1d0925182655c9d
DIFF: 
https://github.com/llvm/llvm-project/commit/222e661c89cfbfd8a6b55e4cd1d0925182655c9d.diff

LOG: [clang][layout] Fix unsigned char overflow in ms_struct bitfield layout 
(#181433)

Fixes #161511

When using MS-struct layout rules (`#pragma ms_struct`), Clang produces
incorrect memory layouts when encountering large `_BitInt` bit-fields.
The reason was that `LastBitfieldStorageUnitSize` variable was declared
as `unsigned char`, which caused it to overflow when the values used
with `_BitInt` exceeded `255`, so I changed it from `unsigned char` to
`uint64_t`.

In the added test, we can clearly see that `f2` and `f3` are both packed
in the same 256-bit unit.

Added: 
    clang/test/Layout/ms-x86-bitfields-overflow.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/RecordLayoutBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2bac5e7b06a59..31107c8dae071 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -49,6 +49,11 @@ C++ Specific Potentially Breaking Changes
 ABI Changes in This Version
 ---------------------------
 
+- Fixed incorrect struct layout for ``_BitInt`` bitfields wider than 255 bits
+  on MSVC targets. Internal bitfield tracking fields were changed from
+  ``unsigned char`` to ``uint64_t`` to prevent overflow. This might be an ABI
+  break for such structs compared to earlier Clang versions.
+
 AST Dumping Potentially Breaking Changes
 ----------------------------------------
 

diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp 
b/clang/lib/AST/RecordLayoutBuilder.cpp
index 36b8eea92c0a4..0b1bf813efd10 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -615,11 +615,11 @@ class ItaniumRecordLayoutBuilder {
   /// this contains the number of bits in the last unit that can be used for
   /// an adjacent bitfield if necessary.  The unit in question is usually
   /// a byte, but larger units are used if IsMsStruct.
-  unsigned char UnfilledBitsInLastUnit;
+  uint64_t UnfilledBitsInLastUnit;
 
   /// LastBitfieldStorageUnitSize - If IsMsStruct, represents the size of the
   /// storage unit of the previous field if it was a bitfield.
-  unsigned char LastBitfieldStorageUnitSize;
+  uint64_t LastBitfieldStorageUnitSize;
 
   /// MaxFieldAlignment - The maximum allowed field alignment. This is set by
   /// #pragma pack.

diff  --git a/clang/test/Layout/ms-x86-bitfields-overflow.c 
b/clang/test/Layout/ms-x86-bitfields-overflow.c
new file mode 100644
index 0000000000000..a6b2461a4d438
--- /dev/null
+++ b/clang/test/Layout/ms-x86-bitfields-overflow.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions 
-fdump-record-layouts -fsyntax-only %s 2>/dev/null \
+// RUN:            | FileCheck %s
+
+// Test that large _BitInt fields do not overflow the internal storage unit 
tracker (previously unsigned char).
+// If the bug exists, this struct splits into two units.
+// If fixed, f1 and f2 are packed into a single unit.
+
+#pragma ms_struct on
+
+struct __attribute__((packed, aligned(1))) A {
+  _BitInt(250) f1 : 2;
+  _BitInt(250) f2 : 2;
+};
+
+struct __attribute__((packed, aligned(1))) B {
+  _BitInt(500) f1 : 2;
+  _BitInt(500) f2 : 255;
+};
+
+// CHECK-LABEL:   0 | struct A{{$}}
+// CHECK-NEXT:0:0-1 |   _BitInt(250) f1
+// CHECK-NEXT:0:2-3 |   _BitInt(250) f2
+// CHECK-NEXT:      | [sizeof=32, align=32]
+
+// CHECK-LABEL:   0 | struct B{{$}}
+// CHECK-NEXT:0:0-1 |   _BitInt(500) f1
+// CHECK-NEXT:0:2-256 |   _BitInt(500) f2
+// CHECK-NEXT:      | [sizeof=64, align=64]
+
+int x[sizeof(struct A)];
+int y[sizeof(struct B)];


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

Reply via email to