https://github.com/MaskRay created 
https://github.com/llvm/llvm-project/pull/182792

For ms_struct structs on Itanium layout targets, the packed attribute is
ignored on bit-fields (2014 commit
76e1818a2b1248579557de2927c135c322577c82), mismatching the GCC behavior.
Remove the `!IsMsStruct` guard to fix it.


>From 7eb24d007ee65b6ccf139f4cb09e34837f8144a8 Mon Sep 17 00:00:00 2001
From: Fangrui Song <[email protected]>
Date: Sun, 22 Feb 2026 18:33:48 -0800
Subject: [PATCH] Fix packed being ignored on ms_struct bitfields

For ms_struct structs on Itanium layout targets, the packed attribute is
ignored on bit-fields (2014 commit
76e1818a2b1248579557de2927c135c322577c82), mismatching the GCC behavior.
Remove the `!IsMsStruct` guard to fix it.
---
 clang/lib/AST/RecordLayoutBuilder.cpp   |  2 +-
 clang/test/CodeGen/ms_struct-bitfield.c |  4 ++--
 clang/test/CodeGen/ms_struct-packed.c   | 18 ++++++++++++++++++
 3 files changed, 21 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGen/ms_struct-packed.c

diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp 
b/clang/lib/AST/RecordLayoutBuilder.cpp
index 36b8eea92c0a4..dd052dd52e76e 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1676,7 +1676,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const 
FieldDecl *D) {
   unsigned UnpackedFieldAlign = FieldAlign;
 
   // Ignore the field alignment if the field is packed unless it has zero-size.
-  if (!IsMsStruct && FieldPacked && FieldSize != 0)
+  if (FieldPacked && FieldSize != 0)
     FieldAlign = 1;
 
   // But, if there's an 'aligned' attribute on the field, honor that.
diff --git a/clang/test/CodeGen/ms_struct-bitfield.c 
b/clang/test/CodeGen/ms_struct-bitfield.c
index 37b0245e57c45..4598b880dd975 100644
--- a/clang/test/CodeGen/ms_struct-bitfield.c
+++ b/clang/test/CodeGen/ms_struct-bitfield.c
@@ -172,5 +172,5 @@ struct {
   __attribute__((packed)) unsigned short c : 6;
 } ATTR t13;
 int s13 = sizeof(t13);
-// CHECK: @s13 ={{.*}} global i32 4
-// CHECK-ARM: @s13 ={{.*}} global i32 4
+// CHECK: @s13 ={{.*}} global i32 3
+// CHECK-ARM: @s13 ={{.*}} global i32 3
diff --git a/clang/test/CodeGen/ms_struct-packed.c 
b/clang/test/CodeGen/ms_struct-packed.c
new file mode 100644
index 0000000000000..0cbf61a759b81
--- /dev/null
+++ b/clang/test/CodeGen/ms_struct-packed.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple x86_64 %s
+
+/// Packed struct: different storage unit types should pack without alignment
+/// padding between storage units.
+struct __attribute__((packed,ms_struct)) P1 {
+  short a : 8;
+  int b : 30;
+};
+
+static int p1[(sizeof(struct P1) == 6) ? 1 : -1];
+
+// Packed struct with char and int fields.
+struct [[gnu::ms_struct,gnu::packed]] P2 {
+  char a : 4;
+  int b : 20;
+};
+
+static int p2[(sizeof(struct P2) == 5) ? 1 : -1];

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

Reply via email to