diff options
| author | Daniel Dunbar <daniel@zuster.org> | 2010-04-20 17:52:30 +0000 |
|---|---|---|
| committer | Daniel Dunbar <daniel@zuster.org> | 2010-04-20 17:52:30 +0000 |
| commit | 20b551a443dd57f1f759ac6888c74232d6662185 (patch) | |
| tree | 0fedd0253479d70ba4ea4fd4bbfd5887130204f4 | |
| parent | 7be315c414969ce4a63e538bee2f5c92d5adb20f (diff) | |
| download | bcm5719-llvm-20b551a443dd57f1f759ac6888c74232d6662185.tar.gz bcm5719-llvm-20b551a443dd57f1f759ac6888c74232d6662185.zip | |
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
| -rw-r--r-- | clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 21 | ||||
| -rw-r--r-- | clang/test/CodeGen/bitfield-2.c | 33 |
2 files changed, 29 insertions, 25 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 7b7394a8196..89b62bfa5a8 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -323,28 +323,19 @@ 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()); + const llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext()); + unsigned NumBytesToAppend = + llvm::RoundUpToAlignment(FieldSize, 8) / 8; - unsigned NumBytesToAppend = - llvm::RoundUpToAlignment(FieldSize, 8) / 8; + if (NumBytesToAppend > 1) + FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend); - 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 FieldTy; } - + // This is a regular union field. LLVMFields.push_back(LLVMFieldInfo(Field, 0)); return Types.ConvertTypeForMemRecursive(Field->getType()); diff --git a/clang/test/CodeGen/bitfield-2.c b/clang/test/CodeGen/bitfield-2.c index 94f275d7d5b..872312f622e 100644 --- a/clang/test/CodeGen/bitfield-2.c +++ b/clang/test/CodeGen/bitfield-2.c @@ -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; }; +struct s6 g6 = { 0xF }; + +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: ret i1 true // CHECK-OPT: } _Bool test_6() { - struct A a; - - a.b = (_Bool)0; - - return (a.b = !a.b); + struct s6 g6 = { 0xF }; + unsigned long long res = 0; + res ^= g6.f0; + res ^= f6_load(&g6); + res ^= g6.f0; + return res; } - |

