On Monday, 22 October 2018 at 14:31:28 UTC, Timon Gehr wrote:
On 22.10.18 16:09, Simen Kjærås wrote:
On Monday, 22 October 2018 at 13:40:39 UTC, Timon Gehr wrote:
module reborked;
import atomic;

void main()@safe{
    auto a=new Atomic!int;
    import std.concurrency;
    spawn((shared(Atomic!int)* a){ ++*a; }, a);
    ++a.tupleof[0];
}

Finally! Proof that MP is impossible. On the other hand, why the hell is that @safe? It breaks all sorts of guarantees about @safety. At a minimum, that should be un-@safe.

Filed in bugzilla: https://issues.dlang.org/show_bug.cgi?id=19326

--
   Simen

Even if this is changed (and it probably should be), it does not fix the case where the @safe function is in the same module. I don't think it is desirable to change the definition of @trusted such that you need to check the entire module if it contains a single @trusted function.

If I can break safety of some (previously correct) code by editing only @safe code, then that's a significant blow to @safe. I think we need a general way to protect data from being manipulated in @safe code in any way, same module or not.

What do you mean by 'previously correct'?

struct Array(T) {
    @safe:
    private int* ptr;
    private int length;
    @disable this();
    this(int n) @trusted {
        ptr = new int[n].ptr;
        length = n;
        foreach (ref e; ptr[0..length])
            e = 123;
    }
    @trusted ref int get(int idx) {
        assert(idx < length);
        return ptr[idx];
    }
}

unittest {
    auto s = Array!int(1);
    assert(s.get(0) == 123);
}

Is this correct code?

What if I add this:

@safe void bork(T)(ref Array!T s) {
    s.length *= 2;
}

unittest {
    auto s = Array!int(1);
    bork(s);
    assert(s.get(1) == 123); // Out of bounds!
}

--
  Simen

Reply via email to