diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 60ef7fe40934..215b39e7432f 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -332,10 +332,26 @@ CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field, if (FieldSize == 0) return 0; + const llvm::Type *FieldTy; + + if (!Field->getDeclName()) { + // This is an unnamed bit-field, which shouldn't affect alignment on the + // struct so we use an array of bytes for it. + + FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext()); + + unsigned NumBytesToAppend = + llvm::RoundUpToAlignment(FieldSize, 8) / 8; + + if (NumBytesToAppend > 1) + FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend); + } else + FieldTy = Types.ConvertTypeForMemRecursive(Field->getType()); + // Add the bit field info. LLVMBitFields.push_back( LLVMBitFieldInfo(Field, ComputeBitFieldInfo(Types, Field, 0, FieldSize))); - return Types.ConvertTypeForMemRecursive(Field->getType()); + return FieldTy; } // This is a regular union field. diff --git a/clang/test/CodeGenCXX/bitfield-layout.cpp b/clang/test/CodeGenCXX/bitfield-layout.cpp index c77c925d8767..94250195f50c 100644 --- a/clang/test/CodeGenCXX/bitfield-layout.cpp +++ b/clang/test/CodeGenCXX/bitfield-layout.cpp @@ -1,9 +1,17 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -// CHECK: = type { i32, [4 x i8] } +// CHECK: %union.Test1 = type { i32, [4 x i8] } union Test1 { int a; int b: 39; -}; +} t1; -Test1 t1; +// CHECK: %union.Test2 = type { i8 } +union Test2 { + int : 6; +} t2; + +// CHECK: %union.Test3 = type { [2 x i8] } +union Test3 { + int : 9; +} t3;