cat > bug.d << CODE
struct FRect
{
float left, top, right, bottom;
}
void formatValue(float obj)
{
static void byRef(ref float a) {}
byRef(obj);
}
void formatValue(FRect val)
{
formatValue(val.left);
formatValue(val.top);
}
struct Foo
{
void bug()
{
formatValue(bounds);
}
@property FRect bounds()
{
if (&this !is null)
return FRect();
else
return FRect();
}
}
CODE
dmd -c -O -inline bug.d
----
Internal error: backend/cg87.c 331
----
The assertion is in
STATIC code * makesure87(elem *e,unsigned offset,int i,unsigned flag)
assert(_8087elems[i].e == NULL);
Debug output for the assertion is
_8087elems[0].e = 0x1050968, .offset = 8
Looks like a place in the floating point stack is still occupied by some older value. No idea how to fix this though.
Comment #1 by yebblies — 2014-06-07T23:57:39Z
I can't reproduce this on win32 or linux64
Comment #2 by code — 2014-06-16T21:36:34Z
Mmh, the codegen assertion vanished with this commit (https://github.com/D-Programming-Language/dmd/commit/9efe7f74c2462e8743f5a479cd04f9be733be4b0).
I reproduced another test case for the issue.
cat > bug.d << CODE
struct FPoint
{
float x, y;
}
struct FRect
{
float left, top, right, bottom;
static FRect calcBounds(FPoint[] )
{
return FRect();
}
}
struct Matrix
{
FRect mapRect(FRect src) {
FPoint[] pts = new FPoint[](1);
pts[0].x = src.left;
pts[0].y = src.top;
return FRect.calcBounds(pts);
}
}
// TODO: FPoint -> Point!T
struct Path
{
@property FRect bounds()
{
if (points.length)
return FRect();
else
return FRect();
}
FPoint[] points;
}
void foo()
{
Matrix mat;
Path path;
mat.mapRect(path.bounds);
}
CODE
The issues first appeared with dmd2.060 and seems to be triggered by assigning tym = TYucent to 16 byte structs that consist of either 4 floats or 2 doubles in elstruct (https://github.com/D-Programming-Language/dmd/blob/5cc1c812227440d199f265dec8fb976bea7ad943/src/backend/cgelem.c#L3077). I don't understand that code good enough to fix the issue though.
Comment #3 by b2.temp — 2019-03-10T21:39:00Z
this works fine nowadays (git 7036b216dcb5d2b8394ae5c12324227c8ca47187), w or w/o -O -inline, -m32 or -m64.