diff options
| -rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Sema/bitfield-layout.c | 15 | 
2 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index cffdcaf743b..139ee60ef80 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -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. diff --git a/clang/test/Sema/bitfield-layout.c b/clang/test/Sema/bitfield-layout.c index d2263914758..2abd139d238 100644 --- a/clang/test/Sema/bitfield-layout.c +++ b/clang/test/Sema/bitfield-layout.c @@ -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)  | 

