← Back to index
|
Original Bugzilla link
Bug 19173 – [scope][dip1000] Using a `lazy` parameter defeats scope and dip1000
Status
RESOLVED
Resolution
INVALID
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-08-16T20:28:57Z
Last change time
2019-09-23T09:19:46Z
Keywords
safe
Assigned to
No Owner
Creator
Atila Neves
Comments
Comment #0
by atila.neves — 2018-08-16T20:28:57Z
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.