diff options
author | Anders Carlsson <andersca@mac.com> | 2010-04-17 21:04:52 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-04-17 21:04:52 +0000 |
commit | d62328e6a0fa933e3a5daaf68e4964031e6c5c5e (patch) | |
tree | d410d84f978d31b2a8b414fb83162eb12bfe91dc | |
parent | 86664465bac330871d4a476f68a1d6f7f6f102af (diff) |
Unnamed bit-fields in a union should be laid out with a type that doesn't affect alignment.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101673 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 18 | ||||
-rw-r--r-- | test/CodeGenCXX/bitfield-layout.cpp | 14 |
2 files changed, 28 insertions, 4 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 60ef7fe409..215b39e743 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/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/test/CodeGenCXX/bitfield-layout.cpp b/test/CodeGenCXX/bitfield-layout.cpp index c77c925d87..94250195f5 100644 --- a/test/CodeGenCXX/bitfield-layout.cpp +++ b/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; |