Skip to content

Commit fed5597

Browse files
committed
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
1 parent 36a02e0 commit fed5597

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
277277
}
278278

279279
void CGRecordLowering::lowerUnion() {
280+
CharUnits LayoutSize = Layout.getSize();
280281
llvm::Type *StorageType = 0;
281282
// Compute zero-initializable status.
282283
if (!D->field_empty() && !isZeroInitializable(*D->field_begin()))
@@ -293,7 +294,10 @@ void CGRecordLowering::lowerUnion() {
293294
// Skip 0 sized bitfields.
294295
if (Field->getBitWidthValue(Context) == 0)
295296
continue;
296-
setBitFieldInfo(*Field, CharUnits::Zero(), getStorageType(*Field));
297+
llvm::Type *FieldType = getStorageType(*Field);
298+
if (LayoutSize < getSize(FieldType))
299+
FieldType = getByteArrayType(LayoutSize);
300+
setBitFieldInfo(*Field, CharUnits::Zero(), FieldType);
297301
}
298302
Fields[*Field] = 0;
299303
llvm::Type *FieldType = getStorageType(*Field);
@@ -304,7 +308,6 @@ void CGRecordLowering::lowerUnion() {
304308
getSize(FieldType) > getSize(StorageType)))
305309
StorageType = FieldType;
306310
}
307-
CharUnits LayoutSize = Layout.getSize();
308311
// If we have no storage type just pad to the appropriate size and return.
309312
if (!StorageType)
310313
return appendPaddingBytes(LayoutSize);

clang/test/CodeGen/union.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,16 @@ typedef union T0 { unsigned int : 0; } T0;
4444
T0 t0;
4545

4646
union { int large_bitfield: 31; char c } u2;
47+
48+
struct dt_t_s {
49+
union {
50+
long long u : 56;
51+
} __attribute__((packed));
52+
};
53+
struct {
54+
struct {
55+
struct {
56+
struct dt_t_s t;
57+
};
58+
};
59+
} a;

0 commit comments

Comments
 (0)