You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typedefstructBitFlags {
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.
typedefstructFoo {
BitFlagsflags;
} 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.
The text was updated successfully, but these errors were encountered:
Compiling via -vv shows that the BitField IR type is an un-packed struct:
* * * * Building struct type test.BitField @ test.d(1)
* * * * * final struct type: %test.BitField = type { i24, [1 x i8] }
so that LLVM is indeed free to add some implicit padding. There might be a missing assertion checking the final aggregate size (IR vs. AST) too, catching this shouldn't require using the type as field of another aggregate.
A quick test case:
In a C file, define
BitFlags
like:or like:
then define a struct which contains
BitFlags
, e.g.The following failure will occur upon compilation:
As far as I can tell, this is the cause:
Within the context of a call to
IrTypeStruct::get
for theBitFlags
struct, inAggrTypeBuilder::addAggregate
when the bitfield-grouping'sgroup.sizeInBytes
(and thus the actual field'ssize
) is 3, 5, 6, or 7 the LLVM type for that bitfield-grouping ends up beingi24
,i40
,i48
, ori56
.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 asi32
, andi40
,i48
,i56
the same asi64
, they have their own implicit padding from LLVM's data-layout, so the tail-padding added by LDC ends up making theBitFlags
struct bigger than it should be.The text was updated successfully, but these errors were encountered: