www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 20149] New: [DIP1000] Local data escapes `opSlice` if not

https://issues.dlang.org/show_bug.cgi?id=20149

          Issue ID: 20149
           Summary: [DIP1000] Local data escapes `opSlice` if not
                    annotated with `return`
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: critical
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: slavo5150 yahoo.com

---
import std.stdio;

 safe:

struct ScopeBuffer(T, size_t Len)
{
    this(T[Len] buf, size_t len = 0)
    {
        this.buf = buf;
                this.len = len;
    }

    // Decorateing `opSlice` with `return`, causes the compiler to correctly
emit
    // a compiler error on line 37, but without `return` a compiler error
should be
    // emitted on line 25
    inout(T)[] opSlice(size_t lower, size_t upper) inout /*return*/
    in
    {
        assert(lower <= len, "Lower bound must be less than or equal to the
length");
        assert(upper <= len, "Upper bound must be less than or equal to the
length");
        assert(lower <= upper, "Lower bound must be less than or equal to the
upper bound");
    }
    do
    {
        return buf[lower .. upper]; //BUG: compiler error shoud be emitted here
                                    // if `opSlice` is not decorated with
`return`
    }

    T[Len] buf;
    size_t len;
}

char[] fun()
{
    char[4] buf = "abcd";
    auto sb = ScopeBuffer!(char, 4)(buf, 4);
    return sb[0..2];  // BUG:  compiler allows data internal to `ScopeBuffer`
to 
                      // escape here unless `ScopeBuffer.opSlize` is decorated
with `return`
}

void main()
{
    auto s = fun();
    writeln(s);
}
---
https://run.dlang.io/is/rNvdwC

Observation-1:  Code compiles with `dmd -preview=dip1000 source.d`
Expectation:  A compiler error should be emitted in `opSlice` where the slice
of `ScopeBuffer`'s `buf` members is escaping.

Observation-2:  Decorating `opSlice` with `return` causes a compiler error to
be correctly emitted where the slice is escaping `foo`, but without `return` a
compiler error should be emitted where the slice is being returned from
`opSlice`.

--
Aug 21 2019