From 30577e6c4f5ba66b8dc832ed9955b1a7475f788a Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Sat, 1 Mar 2014 00:38:40 +0000 Subject: [PATCH] Fixed an assertion failure related to bitfield lowering. When lowering a bitfield, CGRecordLowering would assign the wrong storage type to a bitfield in some cases and trigger an assertion. In these cases the layout was still correct, just the bitfield info was wrong. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202562 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGRecordLayoutBuilder.cpp | 7 +++++-- test/CodeGen/union.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index dd4c0cdb6b..6514361641 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -277,6 +277,7 @@ void CGRecordLowering::lower(bool NVBaseType) { } void CGRecordLowering::lowerUnion() { + CharUnits LayoutSize = Layout.getSize(); llvm::Type *StorageType = 0; // Compute zero-initializable status. if (!D->field_empty() && !isZeroInitializable(*D->field_begin())) @@ -293,7 +294,10 @@ void CGRecordLowering::lowerUnion() { // Skip 0 sized bitfields. if (Field->getBitWidthValue(Context) == 0) continue; - setBitFieldInfo(*Field, CharUnits::Zero(), getStorageType(*Field)); + llvm::Type *FieldType = getStorageType(*Field); + if (LayoutSize < getSize(FieldType)) + FieldType = getByteArrayType(LayoutSize); + setBitFieldInfo(*Field, CharUnits::Zero(), FieldType); } Fields[*Field] = 0; llvm::Type *FieldType = getStorageType(*Field); @@ -304,7 +308,6 @@ void CGRecordLowering::lowerUnion() { getSize(FieldType) > getSize(StorageType))) StorageType = FieldType; } - CharUnits LayoutSize = Layout.getSize(); // If we have no storage type just pad to the appropriate size and return. if (!StorageType) return appendPaddingBytes(LayoutSize); diff --git a/test/CodeGen/union.c b/test/CodeGen/union.c index 5c89e2d72a..7302182102 100644 --- a/test/CodeGen/union.c +++ b/test/CodeGen/union.c @@ -44,3 +44,16 @@ typedef union T0 { unsigned int : 0; } T0; T0 t0; union { int large_bitfield: 31; char c } u2; + +struct dt_t_s { + union { + long long u : 56; + } __attribute__((packed)); +}; +struct { + struct { + struct { + struct dt_t_s t; + }; + }; +} a; -- 2.40.0