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]); }
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(); }
Turns out that this worked on 2.025 and earlier. It also works on D1.
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); }
http://www.dsource.org/projects/dmd/changeset/692