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