From: Fariborz Jahanian Date: Fri, 6 May 2011 21:56:12 +0000 (+0000) Subject: Establish a new alignment for an ms_struct bitfield following X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=52bbe7a1133c3cb57e9246f1b96c12940ea3821a;p=clang Establish a new alignment for an ms_struct bitfield following a non-bitfield if size of their types differ. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131023 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 060ac4b1cf..55aca03fe5 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -411,6 +411,16 @@ public: /// bitfield which follows the bitfield 'LastFD'. bool BitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; + + /// NoneBitfieldFollowsBitfield - return 'true" if 'FD' is not a + /// bitfield which follows the bitfield 'LastFD'. + bool NoneBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// BitfieldFollowsNoneBitfield - return 'true" if 'FD' is a + /// bitfield which follows the none bitfield 'LastFD'. + bool BitfieldFollowsNoneBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::iterator overridden_cxx_method_iterator; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 07823e0408..5271c90bb8 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -558,6 +558,18 @@ bool ASTContext::BitfieldFollowsBitfield(const FieldDecl *FD, LastFD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue()); } +bool ASTContext::NoneBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const { + return (!FD->isBitField() && LastFD && LastFD->isBitField() && + LastFD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue()); +} + +bool ASTContext::BitfieldFollowsNoneBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const { + return (FD->isBitField() && LastFD && !LastFD->isBitField() && + FD->getBitWidth()-> EvaluateAsInt(*this).getZExtValue()); +} + ASTContext::overridden_cxx_method_iterator ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const { llvm::DenseMap::const_iterator Pos diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index ae67c3b394..49c3b58510 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1269,12 +1269,15 @@ void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { // ignored: else if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD)) continue; - else if (Context.BitfieldFollowsBitfield(FD, LastFD)) { + else if (Context.BitfieldFollowsBitfield(FD, LastFD) || + Context.BitfieldFollowsNoneBitfield(FD, LastFD)) { // Adjacent bit fields are packed into the same 1-, 2-, or // 4-byte allocation unit if the integral types are the same // size and if the next bit field fits into the current // allocation unit without crossing the boundary imposed by the // common alignment requirements of the bit fields. + // Also, establish a new alignment for a bitfield following + // a non-bitfield if size of their types differ. std::pair FieldInfo = Context.getTypeInfo(FD->getType()); uint64_t TypeSize = FieldInfo.first; diff --git a/test/CodeGen/ms_struct-bitfield-3.c b/test/CodeGen/ms_struct-bitfield-3.c new file mode 100644 index 0000000000..96782980dc --- /dev/null +++ b/test/CodeGen/ms_struct-bitfield-3.c @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s +// rdar://8823265 + +#define ATTR __attribute__((__ms_struct__)) + +struct _struct_0 +{ + int member_0 : 25 ; + short member_1 : 6 ; + char member_2 : 2 ; + unsigned short member_3 : 1 ; + unsigned char member_4 : 7 ; + short member_5 : 16 ; + int : 0 ; + char member_7 ; + +} ATTR; + +typedef struct _struct_0 struct_0; + +#define size_struct_0 20 + +struct_0 test_struct_0 = { 18557917, 17, 3, 0, 80, 6487, 93 }; +static int a[(size_struct_0 == sizeof (struct_0)) -1];