From: Daniel Dunbar Date: Thu, 22 Apr 2010 14:56:10 +0000 (+0000) Subject: IRgen: Fix case where we might generate an access component with width == 0, if X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4651efb5ba5710c91b58c8b86872b264dd71f464;p=clang IRgen: Fix case where we might generate an access component with width == 0, if we have to narrow the access side immediately (can happen with packed, -fno-bitfield-type-align). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102067 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 17c5640c64..ee8ae5224f 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -215,6 +215,16 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, std::min(AccessWidth - (AccessBitsInFieldStart - AccessStart), FieldSize - (AccessBitsInFieldStart-FieldOffset)); + // If we haven't accessed any target bits yet and narrowed the access size, + // we might not have reached any target bits yet. + // + // FIXME: This test is unnecessarily once we choose the initial acccess size + // more intelligently. + if (!AccessedTargetBits && AccessBitsInFieldSize == 0) { + AccessStart += AccessWidth; + continue; + } + assert(NumComponents < 3 && "Unexpected number of components!"); CGBitFieldInfo::AccessInfo &AI = Components[NumComponents++]; AI.FieldIndex = 0; diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c index 7d6979a542..121bd7cd4f 100644 --- a/test/CodeGen/bitfield-2.c +++ b/test/CodeGen/bitfield-2.c @@ -310,3 +310,38 @@ struct __attribute__((aligned(16))) s7 { int f7_load(struct s7 *a0) { return a0->f0; } + +/***/ + +// This is a case where we narrow the access width immediately. + +struct __attribute__((packed)) s8 { + char f0 : 4; + char f1; + int f2 : 4; + char f3 : 4; +}; + +struct s8 g8 = { 0xF }; + +int f8_load(struct s8 *a0) { + return a0->f0 ^ a0 ->f2 ^ a0->f3; +} +int f8_store(struct s8 *a0) { + return (a0->f0 = 0xFD) ^ (a0->f2 = 0xFD) ^ (a0->f3 = 0xFD); +} +int f8_reload(struct s8 *a0) { + return (a0->f0 += 0xFD) ^ (a0->f2 += 0xFD) ^ (a0->f3 += 0xFD); +} + +// CHECK-OPT: define i32 @test_8() +// CHECK-OPT: ret i32 -3 +// CHECK-OPT: } +unsigned test_8() { + struct s8 g8 = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; + unsigned long long res = 0; + res ^= g8.f0 ^ g8.f2 ^ g8.f3; + res ^= f8_load(&g8) ^ f8_store(&g8) ^ f8_reload(&g8); + res ^= g8.f0 ^ g8.f2 ^ g8.f3; + return res; +}