Thread overview
tupleof vs @safe
Mar 02, 2018
ag0aep6g
Mar 02, 2018
ag0aep6g
Mar 04, 2018
ag0aep6g
March 03, 2018
As far as I understand, this is generally how ref counting is supposed to be done, and with a simple payload like `int` it's supposed to be properly safe already:

----
module my_rc_thingy;
struct RCint
{
    import core.stdc.stdlib: free, malloc;

    private static struct Store
    {
        int payload;
        uint count;
    }
    private Store* s = null;

    int value() @safe { return s.payload; }

    this(int value) @trusted
    {
        s = cast(Store*) malloc(Store.sizeof);
        *s = Store(value, 1);
    }

    this(this) @safe { ++s.count; }

    ~this() @trusted
    {
        if (--s.count == 0)
        {
            free(s);
            s = null;
        }
    }
}
----

(There could be more checks for null, but dereferencing null crashes the program in an `@safe` manner anyway, so why bother in an example.)

I don't have to worry about DIP 1000, because I don't give out references to the payload or to the reference count. Right?

But what about `tupleof`? It ignores `private` and it's allowed in `@safe` code:

----
void main() @safe
{
    import my_rc_thingy: RCint;
    import std.stdio;

    int* p;
    {
        auto rc = RCint(42);
        p = &rc.tupleof[0].payload; /* uh-oh */
    }
    writeln(*p); /* garbage */

    auto rc = RCint(42);
    {
        auto rc2 = rc; /* increasing the refcount */
        rc2.tupleof[0].count = 1; /* uh-oh */
    }
    writeln(rc.value); /* garbage */
}
----

So am I missing something or should `tupleof` not be allowed to ignore `private` in `@safe` code?
March 03, 2018
On 03/03/2018 12:22 AM, ag0aep6g wrote:
> But what about `tupleof`? It ignores `private` and it's allowed in `@safe` code:
> 
> ----
[...]
> ----

Now that I've sent this, I find the affected Phobos type I couldn't pinpoint. It's `File`:

----
void main() @safe
{
    import std.stdio: File, writeln;
    auto hosts = File("/etc/hosts");
    {
        auto hosts_copy = hosts;
        hosts_copy.tupleof[0].refs = 1; /* uh-oh */
    }
    auto self = File(__FILE__);
    writeln(hosts.rawRead(new char[1000]));
        /* Reads from __FILE__ instead of /etc/hosts. */
}
----

https://run.dlang.io/is/1QSsUk
March 04, 2018
On 03/03/2018 12:22 AM, ag0aep6g wrote:
> So am I missing something or should `tupleof` not be allowed to ignore `private` in `@safe` code?

Filed an issue: https://issues.dlang.org/show_bug.cgi?id=18554