From fed55979b1e2f7a33ac9e9ab967bc40ee037a841 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. llvm-svn: 202562 --- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 7 +++++-- clang/test/CodeGen/union.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index dd4c0cdb6b68..651436164177 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/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/clang/test/CodeGen/union.c b/clang/test/CodeGen/union.c index 5c89e2d72a7e..730218210213 100644 --- a/clang/test/CodeGen/union.c +++ b/clang/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;