https://github.com/akramhany updated https://github.com/llvm/llvm-project/pull/181433
>From 84667eae348cbd00867da22eb7c9be15a7576e62 Mon Sep 17 00:00:00 2001 From: akramhany <[email protected]> Date: Sat, 14 Feb 2026 01:04:13 +0200 Subject: [PATCH 1/2] [clang][layout] Fix unsigned char overflow in ms_struct bitfield layout --- clang/lib/AST/RecordLayoutBuilder.cpp | 4 +-- clang/test/Layout/ms-x86-bitfields-overflow.c | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 clang/test/Layout/ms-x86-bitfields-overflow.c 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)]; >From f7995d0666c4fe1917ed776a1d1297fc57a0ae0e Mon Sep 17 00:00:00 2001 From: akramhany <[email protected]> Date: Sun, 22 Feb 2026 10:49:02 +0200 Subject: [PATCH 2/2] [clang][layout] add a release note --- clang/docs/ReleaseNotes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6e9e5baea2921..06a2c92e764bc 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 ---------------------------------------- _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
