[Issue 19173] New: [scope][dip1000] Using a `lazy` parameter defeats scope and dip1000

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Aug 16 20:28:57 UTC 2018


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 at puremagic.com
          Reporter: atila.neves at 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.

--


More information about the Digitalmars-d-bugs mailing list