IRgen: Always use i8 arrays to access union bit-fields. This is ugly, but

matches how we currently handle structs, and this correctly handles
-fno-bitfield-type-align.

llvm-svn: 101918
This commit is contained in:
Daniel Dunbar 2010-04-20 17:52:30 +00:00
parent 7be315c414
commit 20b551a443
2 changed files with 31 additions and 27 deletions

View File

@ -323,21 +323,12 @@ CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
if (FieldSize == 0)
return 0;
const llvm::Type *FieldTy;
const llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
unsigned NumBytesToAppend =
llvm::RoundUpToAlignment(FieldSize, 8) / 8;
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());
if (NumBytesToAppend > 1)
FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend);
// Add the bit field info.
LLVMBitFields.push_back(

View File

@ -175,7 +175,6 @@ unsigned long long test_4() {
/***/
struct s5 {
unsigned f0 : 2;
_Bool f1 : 1;
@ -206,18 +205,32 @@ unsigned long long test_5() {
return res;
}
struct A {
_Bool b : 2;
/***/
struct s6 {
_Bool f0 : 2;
};
// CHECK-OPT: define zeroext i1 @test_6()
// CHECK-OPT: ret i1 true
// CHECK-OPT: }
_Bool test_6() {
struct A a;
struct s6 g6 = { 0xF };
a.b = (_Bool)0;
return (a.b = !a.b);
int f6_load(struct s6 *a0) {
return a0->f0;
}
int f6_store(struct s6 *a0) {
return a0->f0 = 0x0;
}
int f6_reload(struct s6 *a0) {
return (a0->f0 += 0xF);
}
// CHECK-OPT: define zeroext i1 @test_6()
// CHECK-OPT: ret i1 true
// CHECK-OPT: }
_Bool test_6() {
struct s6 g6 = { 0xF };
unsigned long long res = 0;
res ^= g6.f0;
res ^= f6_load(&g6);
res ^= g6.f0;
return res;
}