D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4524 - Regression(2.026) Bus error with nested struct
Summary: Regression(2.026) Bus error with nested struct
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other All
: P2 regression
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2010-07-27 21:48 UTC by Andrei Alexandrescu
Modified: 2015-06-09 05:15 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrei Alexandrescu 2010-07-27 21:48:58 UTC
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 Lars T. Kyllingstad 2010-07-29 13:51:59 UTC
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 Don 2010-09-26 01:37:01 UTC
Turns out that this worked on 2.025 and earlier. It also works on D1.
Comment 3 Don 2010-09-27 03:59:07 UTC
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);
    }
Comment 4 Walter Bright 2010-09-27 13:29:54 UTC
http://www.dsource.org/projects/dmd/changeset/692