aliasing expressions and identifiers

Nick Treleaven via Digitalmars-d digitalmars-d at puremagic.com
Fri May 27 03:04:14 PDT 2016


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.


More information about the Digitalmars-d mailing list