On Thursday, 10 July 2014 at 20:10:38 UTC, Marc Schütz wrote:
struct S {
int* p;
void releaseBuffer() scope {
// `scope` in the signature applies to `this`
free(this.p);
this.p = null;
}
}
int bar(scope ref S a, scope int* b) {
a.releaseBuffer();
return *b; // use after free
}
S s;
bar(s, s.p);
The root cause of the problem here is the call to `free()`. I
_believe_ the solution is that `free()` (and equivalent
functions of allocators as well as `delete`) must not accept
scope parameters.
Thinking more about it:
struct S {
int* p;
void releaseBuffer() scope {
free(this.p);
this.p = null;
}
}
int bar(void delegate() a, scope int* b) {
a();
return *b; // use after free
}
S s;
bar({ s.releaseBuffer(); }, s.p);
So, for what I suggested (`free()` mustn't accept scope) to work,
an additional rule is required: While a borrowed reference exist,
the original must also be treated as scope.
Now, this is much more complicated to implement :-( Maybe there's
a better way?