mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
fix Issue 24262 - Assert error with bit fields (#15864)
This commit is contained in:
parent
e1197fc765
commit
ec34292ead
2 changed files with 70 additions and 18 deletions
|
@ -6522,13 +6522,13 @@ elem *toElemStructLit(StructLiteralExp sle, ref IRState irs, EXP op, Symbol *sym
|
||||||
// CTFE may fill the hidden pointer by NullExp.
|
// CTFE may fill the hidden pointer by NullExp.
|
||||||
{
|
{
|
||||||
VarDeclaration vbf;
|
VarDeclaration vbf;
|
||||||
foreach (i, el; *sle.elements)
|
foreach (i, element; *sle.elements)
|
||||||
{
|
{
|
||||||
if (!el)
|
if (!element)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VarDeclaration v = sle.sd.fields[i];
|
VarDeclaration v = sle.sd.fields[i];
|
||||||
assert(!v.isThisDeclaration() || el.op == EXP.null_);
|
assert(!v.isThisDeclaration() || element.op == EXP.null_);
|
||||||
|
|
||||||
elem *e1;
|
elem *e1;
|
||||||
if (tybasic(stmp.Stype.Tty) == TYnptr)
|
if (tybasic(stmp.Stype.Tty) == TYnptr)
|
||||||
|
@ -6539,50 +6539,73 @@ elem *toElemStructLit(StructLiteralExp sle, ref IRState irs, EXP op, Symbol *sym
|
||||||
{
|
{
|
||||||
e1 = el_ptr(stmp);
|
e1 = el_ptr(stmp);
|
||||||
}
|
}
|
||||||
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
|
|
||||||
|
|
||||||
elem *ep = toElem(el, irs);
|
elem *ep = toElem(element, irs);
|
||||||
|
|
||||||
Type t1b = v.type.toBasetype();
|
Type t1b = v.type.toBasetype();
|
||||||
Type t2b = el.type.toBasetype();
|
Type t2b = element.type.toBasetype();
|
||||||
if (t1b.ty == Tsarray)
|
if (t1b.ty == Tsarray)
|
||||||
{
|
{
|
||||||
|
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v.offset));
|
||||||
if (t2b.implicitConvTo(t1b))
|
if (t2b.implicitConvTo(t1b))
|
||||||
{
|
{
|
||||||
elem *esize = el_long(TYsize_t, t1b.size());
|
elem *esize = el_long(TYsize_t, t1b.size());
|
||||||
ep = array_toPtr(el.type, ep);
|
ep = array_toPtr(element.type, ep);
|
||||||
e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
|
e1 = el_bin(OPmemcpy, TYnptr, e1, el_param(ep, esize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
elem *edim = el_long(TYsize_t, t1b.size() / t2b.size());
|
elem *edim = el_long(TYsize_t, t1b.size() / t2b.size());
|
||||||
e1 = setArray(el, e1, edim, t2b, ep, irs, op == EXP.construct ? EXP.blit : op);
|
e1 = setArray(element, e1, edim, t2b, ep, irs, op == EXP.construct ? EXP.blit : op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tym_t ty = totym(v.type);
|
const tym_t tym = totym(v.type);
|
||||||
e1 = el_una(OPind, ty, e1);
|
auto voffset = v.offset;
|
||||||
if (tybasic(ty) == TYstruct)
|
uint bitfieldArg;
|
||||||
|
uint bitOffset;
|
||||||
|
auto bf = v.isBitFieldDeclaration();
|
||||||
|
if (bf)
|
||||||
|
{
|
||||||
|
const szbits = tysize(tym) * 8;
|
||||||
|
bitOffset = bf.bitOffset;
|
||||||
|
if (bitOffset + bf.fieldWidth > szbits)
|
||||||
|
{
|
||||||
|
const advance = bitOffset / szbits;
|
||||||
|
voffset += advance;
|
||||||
|
bitOffset -= advance * 8;
|
||||||
|
assert(bitOffset + bf.fieldWidth <= szbits);
|
||||||
|
}
|
||||||
|
bitfieldArg = bf.fieldWidth * 256 + bitOffset;
|
||||||
|
|
||||||
|
//printf("2bitOffset %u fieldWidth %u bits %u\n", bitOffset, bf.fieldWidth, szbits);
|
||||||
|
assert(bitOffset + bf.fieldWidth <= szbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, voffset));
|
||||||
|
e1 = el_una(OPind, tym, e1);
|
||||||
|
if (tybasic(tym) == TYstruct)
|
||||||
|
{
|
||||||
e1.ET = Type_toCtype(v.type);
|
e1.ET = Type_toCtype(v.type);
|
||||||
if (auto bf = v.isBitFieldDeclaration())
|
assert(!bf);
|
||||||
|
}
|
||||||
|
if (bf)
|
||||||
{
|
{
|
||||||
if (!vbf || vbf.offset + vbf.type.size() <= v.offset)
|
if (!vbf || vbf.offset + vbf.type.size() <= v.offset)
|
||||||
{
|
{
|
||||||
/* Initialize entire location the bitfield is in
|
/* Initialize entire location the bitfield is in
|
||||||
* ep = (ep & ((1 << bf.fieldWidth) - 1)) << bf.bitOffset
|
* ep = (ep & ((1 << bf.fieldWidth) - 1)) << bf.bitOffset
|
||||||
*/
|
*/
|
||||||
tym_t e1ty = e1.Ety;
|
auto ex = el_bin(OPand, tym, ep, el_long(tym, (1L << bf.fieldWidth) - 1));
|
||||||
auto ex = el_bin(OPand, e1ty, ep, el_long(e1ty, (1L << bf.fieldWidth) - 1));
|
ep = el_bin(OPshl, tym, ex, el_long(tym, bitOffset));
|
||||||
ep = el_bin(OPshl, e1ty, ex, el_long(e1ty, bf.bitOffset));
|
|
||||||
vbf = v;
|
vbf = v;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 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);
|
//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);
|
// Insert special bitfield operator
|
||||||
|
auto mos = el_long(TYuint, bitfieldArg);
|
||||||
e1 = el_bin(OPbit, e1.Ety, e1, mos);
|
e1 = el_bin(OPbit, e1.Ety, e1, mos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,6 +254,34 @@ _Static_assert(test7s2() == -2, "3");
|
||||||
|
|
||||||
/******************************************/
|
/******************************************/
|
||||||
|
|
||||||
|
// https://issues.dlang.org/show_bug.cgi?id=24257
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
unsigned id : 15;
|
||||||
|
_Bool done : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
struct Entry e;
|
||||||
|
};
|
||||||
|
|
||||||
|
void test24257()
|
||||||
|
{
|
||||||
|
int i = 72;
|
||||||
|
struct State s = (struct State){i};
|
||||||
|
if (s.e.id != 72)
|
||||||
|
{
|
||||||
|
printf("error %d\n", __LINE__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test1();
|
test1();
|
||||||
|
@ -263,6 +291,7 @@ int main()
|
||||||
test5();
|
test5();
|
||||||
test6();
|
test6();
|
||||||
test7();
|
test7();
|
||||||
|
test24257();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue