www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19173] New: [scope][dip1000] Using a `lazy` parameter defeats

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

          Issue ID: 19173
           Summary: [scope][dip1000] Using a `lazy` parameter defeats
                    scope and dip1000
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: atila.neves gmail.com

This code correctly does not compile:

-------------------------------------
 safe:

void main() {
    auto oops = Oops(10);
    Oops(10).should == oops[];
}

struct Oops {

    import core.stdc.stdlib;

    private int* _ints;
    private int size;

    this(int size)  trusted { this.size = size; _ints = cast(int*)
malloc(size); }
    ~this()  trusted scope { free(_ints); }
    bool opEqual(ref const(Oops) other) const { return size == other.size; }
    scope auto opSlice(this This)()  trusted { return _ints[0 .. size]; }
}


auto should(E)(lazy E expr) {
    struct Should {
        bool opEquals(int[] ints) {
            assert(expr()[] == ints);
            return true;
        }
    }

    return Should();
}
-------------------------------------


escape_lazy.d(22): Error: variable `escape_lazy.should!(Oops).should.expr` has
scoped destruction, cannot build closure
escape_lazy.d(22): Error: variable `escape_lazy.should!(Oops).should.expr` has
scoped destruction, cannot build closure


Nice. However, slicing the rvalue defeats the compiler check and running under
asan confirms that the resulting code has a use-after-free bug:

`Oops(10)[].should == oops[];`

As can be seen in the code above, making opSlice return a scope slice didn't
seem to affect anything.

--
Aug 16 2018