| // REQUIRED_ARGS: -preview=dip1021 |
| |
| /* Should compile successfully |
| */ |
| |
| |
| struct Allocation { |
| int* ptr; |
| size_t length; |
| } |
| |
| void canFind(scope Allocation); |
| |
| int* malloc(); |
| void free(int*); |
| void pitcher(); |
| void borrow(scope int*); |
| void borrow2c(const scope int*, const scope int*); |
| void out1(out int*); |
| |
| |
| /*****************************/ |
| |
| @live int* foo1(int* p) |
| { |
| return p; // consumes owner |
| } |
| |
| @live int* foo2() |
| { |
| int* p = null; |
| return p; // consumes owner |
| } |
| |
| @live int* foo3(int* p) |
| { |
| scope int* q = p; // borrows from p |
| return p; // use of p ends borrow in q |
| } |
| |
| @live int* foo4(int* p) |
| { |
| scope int* bq = p; // borrow |
| scope const int* cq = p; // const borrow |
| return p; // ends both borrows |
| } |
| |
| /*******************************/ |
| |
| @live void foo5() |
| { |
| auto p = malloc(); |
| scope(exit) free(p); |
| pitcher(); |
| } |
| |
| /*******************************/ |
| |
| void deallocate(int* ptr, size_t length) @live |
| { |
| canFind(Allocation(ptr, length)); // canFind() borrows ptr |
| free(ptr); |
| } |
| |
| |
| /*******************************/ |
| |
| |
| @live int* test1() |
| { |
| auto p = malloc(); |
| scope b = p; |
| return p; |
| } |
| |
| @live int* test2() |
| { |
| auto p = malloc(); |
| auto q = p; |
| return q; |
| } |
| |
| @live void test3() |
| { |
| auto p = malloc(); |
| free(p); |
| } |
| |
| @live void test4() |
| { |
| auto p = malloc(); |
| borrow(p); |
| free(p); |
| } |
| |
| @live void test5() |
| { |
| auto p = malloc(); |
| scope q = p; |
| borrow2c(p, p); |
| free(p); |
| } |
| |
| @live void test6() |
| { |
| int* p = void; |
| out1(p); // initialize |
| free(p); // consume |
| } |
| |
| |
| /*******************************/ |
| |
| void zoo1(int); |
| |
| @live void zoo2() { |
| int* p = malloc(); |
| zoo1(*p); // does not consume p |
| free(p); |
| } |
| |
| @live void zoo3() { |
| int** p = cast(int**)malloc(); |
| free(*p); // consumes p |
| } |
| |
| @live void zoo4() { |
| int[] a = malloc()[0 .. 1]; |
| zoo1(a[0]); // does not consume a |
| free(a.ptr); // consumes a |
| } |
| |
| @live void zoo5() { |
| int*[] a = (cast(int**)malloc())[0 .. 1]; |
| free(a[0]); // consumes a |
| } |
| |
| struct S { int i; int* p; } |
| |
| @live void zoo6() { |
| S* s = cast(S*)malloc(); |
| zoo1(s.i); // does not consume s |
| free(cast(int*)s); |
| } |
| |
| @live void zoo7() { |
| S* s = cast(S*)malloc(); |
| free(s.p); // consumes s |
| } |