-
-
Notifications
You must be signed in to change notification settings - Fork 282
Assertion failure when a struct contains a struct which contains bit fields spanning [17, 25) or [33, 57) bits. #4646
Description
A quick test case:
In a C file, define BitFlags like:
typedef struct BitFlags {
unsigned int _00 : 1;
unsigned int _01 : 1;
unsigned int _02 : 1;
unsigned int _03 : 1;
unsigned int _04 : 1;
unsigned int _05 : 1;
unsigned int _06 : 1;
unsigned int _07 : 1;
unsigned int _08 : 1;
unsigned int _09 : 1;
unsigned int _10 : 1;
unsigned int _11 : 1;
unsigned int _12 : 1;
unsigned int _13 : 1;
unsigned int _14 : 1;
unsigned int _15 : 1;
unsigned int _16 : 1;
} BitFlags;or like:
typedef struct BitFlags {
unsigned long long _00 : 1;
unsigned long long _01 : 1;
unsigned long long _02 : 1;
unsigned long long _03 : 1;
unsigned long long _04 : 1;
unsigned long long _05 : 1;
unsigned long long _06 : 1;
unsigned long long _07 : 1;
unsigned long long _08 : 1;
unsigned long long _09 : 1;
unsigned long long _10 : 1;
unsigned long long _11 : 1;
unsigned long long _12 : 1;
unsigned long long _13 : 1;
unsigned long long _14 : 1;
unsigned long long _15 : 1;
unsigned long long _16 : 1;
unsigned long long _17 : 1;
unsigned long long _18 : 1;
unsigned long long _19 : 1;
unsigned long long _20 : 1;
unsigned long long _21 : 1;
unsigned long long _22 : 1;
unsigned long long _23 : 1;
unsigned long long _24 : 1;
unsigned long long _25 : 1;
unsigned long long _26 : 1;
unsigned long long _27 : 1;
unsigned long long _28 : 1;
unsigned long long _29 : 1;
unsigned long long _30 : 1;
unsigned long long _31 : 1;
unsigned long long _32 : 1;
} BitFlags;then define a struct which contains BitFlags, e.g.
typedef struct Foo {
BitFlags flags;
} Foo;The following failure will occur upon compilation:
Assertion failed: fieldSize <= af.size, file D:\a\ldc\ldc\ir\irtypeaggr.cpp, line 219
As far as I can tell, this is the cause:
Within the context of a call to IrTypeStruct::get for the BitFlags struct, in AggrTypeBuilder::addAggregate when the bitfield-grouping's group.sizeInBytes (and thus the actual field's size) is 3, 5, 6, or 7 the LLVM type for that bitfield-grouping ends up being i24, i40, i48, or i56.
Then, because sd->structsize is 4 or 8, AggrTypeBuilder::addTailPadding ends up adding some bytes of padding after the bitfield's non-power-of-two-sized integer.
But as i24 has same ABI alignment as i32, and i40, i48, i56 the same as i64, they have their own implicit padding from LLVM's data-layout, so the tail-padding added by LDC ends up making the BitFlags struct bigger than it should be.