Index: lib/AST/RecordLayoutBuilder.cpp =================================================================== --- lib/AST/RecordLayoutBuilder.cpp +++ lib/AST/RecordLayoutBuilder.cpp @@ -1345,6 +1345,14 @@ LayoutField(Field); } +// 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, @@ -1382,7 +1390,9 @@ 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 @@ -1607,9 +1617,9 @@ // 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) { Index: test/Layout/itanium-union-bitfield.cpp =================================================================== --- /dev/null +++ test/Layout/itanium-union-bitfield.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fdump-record-layouts %s 2>/dev/null \ +// RUN: | FileCheck %s + +union A { + int f1: 3; + A(); +}; + +A::A() {} + +union B { + int f1: 69; + B(); +}; + +B::B() {} + +// CHECK:*** Dumping AST Record Layout +// CHECK-NEXT: 0 | union A +// CHECK-NEXT: 0 | int f1 +// CHECK-NEXT: | [sizeof=4, dsize=1, align=4 +// CHECK-NEXT: | nvsize=1, nvalign=4] + +// CHECK:*** Dumping AST Record Layout +// CHECK-NEXT: 0 | union B +// CHECK-NEXT: 0 | int f1 +// CHECK-NEXT: | [sizeof=16, dsize=9, align=8 +// CHECK-NEXT: | nvsize=9, nvalign=8] +