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?

Reply via email to