On Thursday, 26 May 2016 at 08:29:41 UTC, Marc Schütz wrote:
On Wednesday, 25 May 2016 at 19:47:06 UTC, Nick Treleaven wrote:
On 24/05/2016 14:48, Nick Treleaven wrote:
@safe unittest
{
     RCArray!int arr;
+      arr.length = 1;
     ref r = arr[0];
arr.destroy; // refcount drops to zero, arr.impl memory freed
     r++; // writes to unallocated memory
}

Here I think local refs must be prevented from initialization by return ref (-dip25). The @rc DIP and RCArray would use return ref. It would be OK to initialize a local ref with a ref function result that is not return ref.
...

To elaborate: neither `scope` nor reference counting can ever protect you against explicit premature destruction of a still-referenced owner. But there is a slightly different problematic scenario:

RCArray!int arr = [7];
ref r = arr[0];
arr = [9];        // this releases the old array
r++;              // use after free

This is the same situation. There's nothing special about destroy, it just assigns arr = arr.init. destroy is @safe so in fact it must work with safe RC. You seem to have ignored my suggestion (which maybe wasn't clear enough) to statically prevent the above from compiling using:

RCArray(T) {
    ...
    ref opIndex(size_t) return;

Local refs cannot be assigned from a function returning ref if that function has any parameters marked with the return attribute. If there is no attribute, local refs + function returning ref is OK.

But this issue exists even without locale `ref`s:

void foo() {
    RCArray!int arr = [7];
    bar(arr, arr[0]);
}

void bar(ref RCArray!int arr, ref int r) {
    arr = [9];    // this releases the old array
    r++;          // use after free
}

This is the reason for the @rc DIP.

It can be solved in one of two ways: Either by making the owner (`arr`) non-mutable during the existence of the references, thereby forbidding the call to `bar()` (I would prefer this one, as it's cleaner and can be used for many more things, e.g. the byLine problem)

I don't see directly how this affects byLine.front, that does not return a reference.

Reply via email to