]> granicus.if.org Git - clang/commitdiff
Fixing a compiler assertion with zero-width bit-fields in packed structs.
authorYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Thu, 13 Feb 2014 02:45:10 +0000 (02:45 +0000)
committerYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Thu, 13 Feb 2014 02:45:10 +0000 (02:45 +0000)
According to the GNU docs, zero-sized bitfields should not be affected by the
packed attribute.

Differential Revision: http://llvm-reviews.chandlerc.com/D2693

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201288 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
test/Sema/bitfield-layout.c

index cffdcaf743b026cd67d545e3bdaae010a1f2a3dc..139ee60ef8029f15af49deea96fd0d6e30e4f3cb 100644 (file)
@@ -1552,8 +1552,8 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
   // Remember the alignment we would have used if the field were not packed.
   unsigned UnpackedFieldAlign = FieldAlign;
 
-  // Ignore the field alignment if the field is packed.
-  if (!IsMsStruct && FieldPacked)
+  // Ignore the field alignment if the field is packed unless it has zero-size.
+  if (!IsMsStruct && FieldPacked && FieldSize != 0)
     FieldAlign = 1;
 
   // But, if there's an 'aligned' attribute on the field, honor that.
index d22639147586c01e4ad5ee7e48b0ed4927d40b99..2abd139d238f1894486eec12107cf7f8706bb486 100644 (file)
@@ -9,6 +9,21 @@ struct a {char x; int : 0; char y;};
 CHECK_SIZE(struct, a, 5)
 CHECK_ALIGN(struct, a, 1)
 
+// Zero-width bit-fields with packed
+struct __attribute__((packed)) a2 { short x : 9; char : 0; int y : 17; };
+CHECK_SIZE(struct, a2, 5)
+CHECK_ALIGN(struct, a2, 1)
+
+// Zero-width bit-fields at the end of packed struct
+struct __attribute__((packed)) a3 { short x : 9; int : 0; };
+CHECK_SIZE(struct, a3, 4)
+CHECK_ALIGN(struct, a3, 1)
+
+// For comparison, non-zero-width bit-fields at the end of packed struct
+struct __attribute__((packed)) a4 { short x : 9; int : 1; };
+CHECK_SIZE(struct, a4, 2)
+CHECK_ALIGN(struct, a4, 1)
+
 union b {char x; int : 0; char y;};
 CHECK_SIZE(union, b, 1)
 CHECK_ALIGN(union, b, 1)