September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #9 from Luís Ferreira <contact@lsferreira.net> ---
(In reply to Dennis from comment #8)
> Reduces to:
> 
> ```D
> void main() @safe
> {
>     foreach(ref e; new int[1])
>         int* f = &e;
> }
> ```

Thanks! So, maybe this should also be valid, but more arguable if requires dip1000 internal checks the same way with `ref`, although, spec-wise it should:

```
void main() @safe
{
    foreach(e; new int[1])
        int* f = &e;
}
```

I removed the `ref`, `f` doesn't escape its own scope, the same way this should compile:

```
void main() @safe
{
    int e;
    int* f = &e;
}
```

--
September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #10 from Dominikus Dittes Scherkl <dominikus@scherkl.de> ---
(In reply to Luís Ferreira from comment #4)
> > Pointers are not allowed in @safe functions at all.
> 
> What are you talking about? They are, its specified in the spec. 20.24.1. Safe Functions.

Sorry.

I misread your code. And of course the compiler could allow for some more patterns to be considered @safe, but I thought that was intentional so.

E.g. the following (a simple self-reference check) is also not considered @safe and I was told that this is intentional without DIP1000:

```
struct Foo
{
   Foo opAssign(const ref Foo f)
   {
      if(&f == this) return this;
      ...
   }
}
```

I'm glad if this is considered a design-flaw that should be fixed.

--
September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #11 from Dennis <dkorpel@live.nl> ---
> the same way this should compile

> I'm glad if this is considered a design-flaw that should be fixed.

Without `-preview=dip1000` taking the address of local, stack allocated variables is not @safe. This is not going to be fixed, we're not going to add special cases to allow a halfway, in between form of safe stack pointers. It's all or nothing.

The question here is whether a `ref` variable counts as a local variable. `ref` parameters freely bind to any lvalue in @safe code, including local variables, so the answer there is yes.

A ref loop variable in foreach is a bit more difficult, as it depends on the type of the thing you're iterating over.

In theory, in the absence of -preview=dip1000, it can't be a stack pointer when you're iterating over a dynamic array, so this issue's test case can be made `@safe` on the basis of that.

On the other hand, there's still the gaping hole that local static arrays can be sliced in `@safe` code without `-preview=dip1000`, and get an unrestricted lifetime. So fixing this issue facilitates more exploitation of that hole (issue 24750).

So perhaps we need to make that a deprecation first and then consider adding a special for this, but whether that's worth it depends on the future direction of dip1000 vs Robert's Simple Safe D.

--
September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #12 from Nick Treleaven <nick@geany.org> ---
(In reply to Dennis from comment #8)
> Reduces to:
> 
> ```D
> void main() @safe
> {
>     foreach(ref e; new int[1])
>         int* f = &e;
> }
> ```

The compiler doesn't know (without optimization or -dip1000) that the program is equivalent to that. It doesn't know below that `f` doesn't escape the scope of foobar somehow.

    @safe
    void foobar()
    {
        int* f;
        foreach(ref e; foo)
            f = &e;
    }

So it seems counter-intuitive to the way D's semantic analysis works to allow this case without -dip1000.

--
September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #13 from Nick Treleaven <nick@geany.org> ---
(In reply to Nick Treleaven from comment #3)
>     @safe
>     int* foobar()
>     {
>         int* f;
>         foreach(ref e; foo)
>             f = &e; // escaping address of foo[0]
>         return f;
>     }

BTW with dmd git master and -dip1000, the static array escape is now caught:

Error: scope variable `f` may not be returned

--
September 13
https://issues.dlang.org/show_bug.cgi?id=24754

--- Comment #14 from Dennis <dkorpel@live.nl> ---
(In reply to Nick Treleaven from comment #12)
> The compiler doesn't know (without optimization or -dip1000) that the
> program is equivalent to that.

It could, all it needs to know is that typeof(Foo.foo) == typeof(new int[1]) ==
int[].

> It doesn't know below that `f` doesn't escape
> the scope of foobar somehow.

Doesn't mattter, `f` may escape, unless it's a `scope int[]`, which doesn't really exist without `-preview=dip1000`.

--
1 2
Next ›   Last »