Bug 4524 – Regression(2.026) Bus error with nested struct
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2010-07-27T21:48:00Z
Last change time
2015-06-09T05:15:14Z
Keywords
patch, wrong-code
Assigned to
nobody
Creator
andrei
Comments
Comment #0 by andrei — 2010-07-27T21:48:58Z
The code below causes a bus error on OSX:
import std.stdio, std.range;
void main()
{
struct BiRange
{
int[] payload;
@property bool empty() { return payload.empty; }
@property BiRange save() { return this; }
@property ref int front() { return payload[0]; }
@property ref int back() { return payload[$ - 1]; }
void popFront() { return payload.popFront(); }
// void popBack() { return payload.popBack(); }
}
auto r = BiRange([1, 2, 3, 10, 11, 4]);
}
Comment #1 by bugzilla — 2010-07-29T13:51:59Z
It causes a segmentation fault on Linux too. Here's a reduced test case without any imports:
void g(int j) { }
void main()
{
struct S
{
int i;
void f() { g(i); }
}
auto s = S();
}
Comment #2 by clugdbug — 2010-09-26T01:37:01Z
Turns out that this worked on 2.025 and earlier. It also works on D1.
Comment #3 by clugdbug — 2010-09-27T03:59:07Z
Caused by the fix to bug 2619. When setting the hidden pointer, the wrong offset is used, which overwrites the return stack instead. Yikes.
e2ir.c, StructLiteralExp::toElem(), line 4849. Shouldn't be adjusting the 'this' pointer, because setEthis() does already adds ad->vthis->offset to it.
All tests in the test suite have v->offset == 0, so this wasn't noticed before.
------
if (sd->isnested)
{ // Initialize the hidden 'this' pointer
assert(sd->fields.dim);
Dsymbol *s = (Dsymbol *)sd->fields.data[sd->fields.dim - 1];
ThisDeclaration *v = s->isThisDeclaration();
assert(v);
elem *e1;
if (tybasic(stmp->Stype->Tty) == TYnptr)
{ e1 = el_var(stmp);
e1->EV.sp.Voffset = soffset;
}
else
{ e1 = el_ptr(stmp);
if (soffset)
e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, soffset));
}
- e1 = el_bin(OPadd, TYnptr, e1, el_long(TYsize_t, v->offset));
e1 = setEthis(loc, irs, e1, sd);
e = el_combine(e, e1);
}