www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 15832] New: Crashing program when a helper template function

https://issues.dlang.org/show_bug.cgi?id=15832

          Issue ID: 15832
           Summary: Crashing program when a helper template function is
                    used to create a template struct
           Product: D
           Version: D2
          Hardware: x86_64
               URL: http://dlang.org/
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P3
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: atila.neves gmail.com

The code below crashes when compiled and run. The seemingly equivalent code
obtained by commenting out `auto m = mock(dg)` and using `auto m =
Mock!(typeof(dg)(dg)` instead works as intended. I can't get what's going on -
it seems to have to do with the `_returns` variable.

import std.traits;

int delegate(int) dg;

static this() {
    dg = (i) => i * 2;
}


struct MockScope(T) {
    this(T)(ref T oldFunc, T newFunc) {
        _oldFuncPtr = &oldFunc;
        _oldFunc = oldFunc;
        oldFunc = newFunc;
    }

    ~this() {
        *_oldFuncPtr = _oldFunc;
    }

 private:

    T* _oldFuncPtr;
    T _oldFunc;
}

struct Mock(T) {
    this(ref T func) {
        _returns = [ReturnType!T.init];
        ReturnType!T inner(ParameterTypeTuple!T values) {
            auto ret = _returns[0];
            return ret;
        }
        func = &inner;
        _scope = MockScope!(T)(func, &inner);
    }

    void returnValue(V...)(V value) {
        _returns.length = 0;
        foreach(v; value) _returns ~= v;
    }

    MockScope!T _scope;
    ReturnType!T[] _returns;
}

auto mock(T)(T f) {
    return Mock!T(f);
}

void main() {
    //auto m = Mock!(typeof(dg))(dg); //this works
    auto m = mock(dg); // this should be equivalent but crashes
    assert(dg(3) == 0);
    m.returnValue(42);
    assert(dg(3) == 42);
}

--
Mar 25 2016