From: Artyom Skrobov Date: Fri, 17 Oct 2014 10:22:03 +0000 (+0000) Subject: D5775: Fix of assertion failure in case of non-POD unions with bitfields. Patch by... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1aa244cfbb7f6c763e6335a260be6d3bedf5122;p=clang D5775: Fix of assertion failure in case of non-POD unions with bitfields. Patch by Evgeny Astigeevich! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220031 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index f0a701930c..d8966f888e 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1335,6 +1335,14 @@ void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { LayoutField(Field, InsertExtraPadding); } +// Rounds the specified size to have it a multiple of the char size. +static uint64_t +roundUpSizeToCharAlignment(uint64_t Size, + const ASTContext &Context) { + uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); + return llvm::RoundUpToAlignment(Size, CharAlignment); +} + void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize, bool FieldPacked, @@ -1372,7 +1380,9 @@ void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit; if (IsUnion) { - setDataSize(std::max(getDataSizeInBits(), FieldSize)); + uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, + Context); + setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize)); FieldOffset = 0; } else { // The bitfield is allocated starting at the next offset aligned @@ -1597,9 +1607,9 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // For unions, this is just a max operation, as usual. if (IsUnion) { - // FIXME: I think FieldSize should be TypeSize here. - setDataSize(std::max(getDataSizeInBits(), FieldSize)); - + uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, + Context); + setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize)); // For non-zero-width bitfields in ms_struct structs, allocate a new // storage unit if necessary. } else if (IsMsStruct && FieldSize) {