As we all should know, std.conv.emplace does not play well with closures:

void main()
{
    int x = 42;
    struct S
    {
        auto getX() { return x; }
    }

    S s;
    assert(s.getX == x);

    auto ps = someBuffer.emplace!S();
    assert(s.getX == x);                // SEGFAULT!
}

As this is not fixable (we cannot pass closures around in D), we should IMHO forbid such usages of emplace (i.e. static assert(!isNested!S))

I was already working on this, when I stumbled upon this unittest in std.conv (simplified):

unittest
{
    int i = 0;
    struct S1
    {
        void foo(){++i;}
    }
    S1 sa = void;
    S1 sb;
    emplace(&sa, sb);   // automagically works
    sa.foo();
    assert(i == 1);
}

Of course there's no way to distinguish between this (legitimate?) use case and the former one, so preventing those segfaults will also prohibit this kind of usage.

What I'd like to know: is this usage widespread? Should we forbid it for the sake of security?

Reply via email to