Unnamed bit-fields in a union should be laid out with a type that doesn't affect alignment.

llvm-svn: 101673
This commit is contained in:
Anders Carlsson 2010-04-17 21:04:52 +00:00
parent 1de2f5710b
commit 2295f13bb0
2 changed files with 28 additions and 4 deletions

View File

@ -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.

View File

@ -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;