Understanding DIP 1000 semantics -- Where's the bug?

Jacob Carlborg doob at me.com
Sun Sep 22 17:53:22 UTC 2019


On 2019-09-22 19:26, Mike Franklin wrote:
> On Sunday, 22 September 2019 at 08:49:14 UTC, ag0aep6g wrote:
> 
>> Then it's possibility 2: `foo2` should error. Your code can easily be 
>> expanded to demonstrate memory corruption:
>>
>> ----
>> @safe:
>>
>> immutable(int)* ip;
>>
>> // Exhibit B
>> //--------------------------
>> int getValue2(ref immutable int i)
>> {
>>     immutable int* my_ip = &i;
>>     ip = my_ip;
>>     return i;
>> }
>>
>> int* foo2()
>> {
>>     immutable int value = 42;
>>     int[] y;
>>     y ~= getValue2(value); // No error
>>     return &y[0];
>> }
>>
>> void main()
>> {
>>     auto p = foo2();
>>     import std.stdio;
>>     writeln(*ip); /* Prints "42". */
>>     writeln(*ip); /* Prints garbage. An immutable value has changed. */
>> }
>> ----
> 
> Interestingly, taking the address of a `ref` in `@safe` code is 
> prevented, but only when compiling *without* -preview=dip1000. See 
> https://run.dlang.io/is/GArFzk
> 
> That's seems like a bug to me.

With DIP1000 enabled the compiler can figure out that it is safe to take 
the address of `i` and assign it to `my_ip`. It seems to fail to 
recognize that assigning to `ip` is unsafe. Perhaps that requires data 
flow analysis.

If you assign directly to `ip` it fails to compile.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list