From a91d38a435431672404a65030f6b5896e4564d0e Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 2 Dec 2011 02:38:48 +0000 Subject: [PATCH] Fix bitfield handling for record layout with #pragma pack. and PR9560. llvm-svn: 145673 --- clang/lib/AST/RecordLayoutBuilder.cpp | 8 +++-- clang/test/Sema/pragma-pack-5.c | 45 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/pragma-pack-5.c diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 88a90a417291..c92116ac6c40 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -1690,18 +1690,20 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment()); // The maximum field alignment overrides the aligned attribute. - if (!MaxFieldAlignment.isZero()) { + if (!MaxFieldAlignment.isZero() && FieldSize != 0) { unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); } // Check if we need to add padding to give the field the correct alignment. - if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) + if (FieldSize == 0 || (MaxFieldAlignment.isZero() && + (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); if (FieldSize == 0 || - (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize) + (MaxFieldAlignment.isZero() && + (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, UnpackedFieldAlign); diff --git a/clang/test/Sema/pragma-pack-5.c b/clang/test/Sema/pragma-pack-5.c new file mode 100644 index 000000000000..95bbe1fe7e94 --- /dev/null +++ b/clang/test/Sema/pragma-pack-5.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify -ffreestanding +// and PR9560 +// Check #pragma pack handling with bitfields. + +#include +#pragma pack(2) + +struct s0 { + char f1; + unsigned f2 : 32; + char f3; +}; +extern int check[sizeof(struct s0) == 6 ? 1 : -1]; + +struct s1 { + char f1; + unsigned : 0; + char f3; +}; +extern int check[sizeof(struct s1) == 5 ? 1 : -1]; + +struct s2 { + char f1; + unsigned : 0; + unsigned f3 : 8; + char f4; +}; +extern int check[sizeof(struct s2) == 6 ? 1 : -1]; + +struct s3 { + char f1; + unsigned : 0; + unsigned f3 : 16; + char f4; +}; +extern int check[sizeof(struct s3) == 8 ? 1 : -1]; +extern int check[offsetof(struct s3, f4) == 6 ? 1 : -1]; + +struct s4 { + char f1; + unsigned f2 : 8; + char f3; +}; +extern int check[sizeof(struct s4) == 4 ? 1 : -1]; +extern int check[offsetof(struct s4, f3) == 2 ? 1 : -1];