I'm getting a strange assertion/crash involving RefCounted and I've reduced it down to the isolated case (see below). This is with D 2.071 and requires this version to compile.

I'm wondering if there is something I wrong in the way I'm using RefCounted. I'm using using it to pass RC value types through chained calls, which should be ok. This seems more like a compiler bug due to the strangeness of the fix lines. The compiler seems confused by the two methods names query in separate classes (removing the first def and the issue goes away). The 2nd fix is on an unused RC. It could also be that there is underlying memory corruption that is intermittent and I just haven't found the problem.

This is a big issue for my design so hopefully the problem can be identified.

erik


import std.typecons;

struct BasicDatabase(Impl) {
    alias Connection = BasicConnection!Impl;

    this(string defaultURI) {data = Data(null);}
    auto connection() {return Connection(this);}

    private:
    alias RefCounted!(Impl, RefCountedAutoInitialize.no) Data;
    Data data;
}

struct BasicConnection(Impl) {
    alias Statement = BasicStatement!Impl;
    alias Database = BasicDatabase!Impl;

    auto statement() {return Statement(this);}
auto query() {return statement().query();} // === remove to fix 1

    this(Database db) {
        //database = db;
        data = Data(&db.data.refCountedPayload());
    }

    private:
    alias RefCounted!(Impl, RefCountedAutoInitialize.no) Data;
    Database database; // === remove to fix 2
    Data data;
}

struct BasicStatement(Impl) {
    alias Connection = BasicConnection!Impl;
    alias Result = BasicResult!Impl;

    this(Connection c) {
        con = c;
        data = Data(&con.data.refCountedPayload());
    }

    auto query() {return Result(this);}

    private:
    alias RefCounted!(Impl, RefCountedAutoInitialize.no) Data;
    Data data;
    Connection con;
}

struct BasicResult(Impl) {
    alias Statement = BasicStatement!Impl;

    this(Statement s) {
        stmt = s;
        data = Data(&stmt.data.refCountedPayload());
    }

    private:
    alias RefCounted!(Impl, RefCountedAutoInitialize.no) Data;
    Statement stmt;
    Data data;
}

struct Payload {
    this(Payload *p) {}
}

void main() {
    auto db = BasicDatabase!Payload("source");
    auto s = db.connection().statement();
    auto r = s.query();
}



core.exception.AssertError@std/typecons.d(4860): Assertion failure
----------------
4 bug 0x00000001063c3f20 _d_assert + 104 5 bug 0x00000001063dc3ca void std.typecons.__assert(int) + 38 6 bug 0x00000001063bae4e nothrow @nogc void std.typecons.__T10RefCountedTS3bug7PayloadVE3std8typecons24RefCountedAutoInitializei0Z.RefCounted.__dtor() + 54 7 bug 0x00000001063ba8c5 nothrow @nogc void bug.BasicStatement!(bug.Payload).BasicStatement.__fieldDtor() + 29 8 bug 0x00000001063ba096 _Dmain + 210 9 bug 0x00000001063d48b3 D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 39 10 bug 0x00000001063d47e7 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) + 35 11 bug 0x00000001063d4858 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() + 44 12 bug 0x00000001063d47e7 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) + 35 13 bug 0x00000001063d474d _d_run_main + 497 14 bug 0x00000001063ba19b main + 15 15 libdyld.dylib 0x00007fff977f35ac start + 0
16  ???                                 0x0000000000000000 0x0 + 0
bug(39873,0x7fff7838d000) malloc: *** error for object 0x7fdea9c03d18: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

Reply via email to