Skip to content

Commit

Permalink
fix Issue 24257 - ImportC: ICE on accessing last _Bool bitfield (#15861)
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored Nov 25, 2023
1 parent 27b891c commit e1197fc
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
34 changes: 28 additions & 6 deletions compiler/src/dmd/e2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -3096,16 +3096,36 @@ elem* toElem(Expression e, ref IRState irs)
e = addressElem(e, tb1);
typ = tybasic(e.Ety);
}
auto offset = el_long(TYsize_t, v.offset);
offset = objc.getOffset(v, tb1, offset);
e = el_bin(OPadd, typ, e, offset);

const tym = totym(dve.type);
auto voffset = v.offset;
uint bitfieldarg = 0;
auto bf = v.isBitFieldDeclaration();
if (bf)
{
// adjust bit offset for bitfield so the type tym encloses the bitfield
const szbits = tysize(tym) * 8;
auto bitOffset = bf.bitOffset;
if (bitOffset + bf.fieldWidth > szbits)
{
const advance = bf.bitOffset / szbits;
voffset += advance;
bitOffset -= advance * 8;
assert(bitOffset + bf.fieldWidth <= szbits);
}
//printf("voffset %u bitOffset %u fieldWidth %u bits %u\n", cast(uint)voffset, bitOffset, bf.fieldWidth, szbits);
bitfieldarg = bf.fieldWidth * 256 + bitOffset;
}

auto eoffset = el_long(TYsize_t, voffset);
e = el_bin(OPadd, typ, e, objc.getOffset(v, tb1, eoffset));
if (v.storage_class & (STC.out_ | STC.ref_))
e = el_una(OPind, TYnptr, e);
e = el_una(OPind, totym(dve.type), e);
if (auto bf = v.isBitFieldDeclaration())
e = el_una(OPind, tym, e);
if (bf)
{
// Insert special bitfield operator
auto mos = el_long(TYuint, bf.fieldWidth * 256 + bf.bitOffset);
auto mos = el_long(TYuint, bitfieldarg);
e = el_bin(OPbit, e.Ety, e, mos);
}
if (tybasic(e.Ety) == TYstruct)
Expand Down Expand Up @@ -6561,6 +6581,8 @@ elem *toElemStructLit(StructLiteralExp sle, ref IRState irs, EXP op, Symbol *sym
{
// Insert special bitfield operator
auto mos = el_long(TYuint, bf.fieldWidth * 256 + bf.bitOffset);
//printf("2bitOffset %u fieldWidth %u bits %u\n", bf.bitOffset, bf.fieldWidth, tysize(e1.Ety) * 8);
assert(bf.bitOffset + bf.fieldWidth <= tysize(e1.Ety) * 8);
e1 = el_bin(OPbit, e1.Ety, e1, mos);
}
}
Expand Down
34 changes: 34 additions & 0 deletions compiler/test/runnable/dbitfields.d
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,39 @@ static assert(test7u() == 1);
static assert(test7s() == -1);
static assert(test7s2() == -2);

/******************************************/
// https://issues.dlang.org/show_bug.cgi?id=24257

struct S24257
{
uint : 15;
bool done : 1;
}

bool advance()
{
S24257 n;
n.done = false;
n.done = true;
return n.done;
}

bool retard()
{
S24257 n;
n.done = true;
n.done = false;
return n.done;
}

static assert(advance() == true);

void test24257()
{
assert(advance() == true);
assert(retard() == false);
}

/******************************************/

int main()
Expand All @@ -184,6 +217,7 @@ int main()
test5();
test6();
test7();
test24257();

return 0;
}

0 comments on commit e1197fc

Please sign in to comment.