Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix issue #21640: @LiVe not working with templates
Signed-off-by: Luís Ferreira <contact@lsferreira.net>
- Loading branch information
Showing
3 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// REQUIRED_ARGS: -preview=dip1021 | ||
|
||
void* malloc(); | ||
|
||
@live T* foo1(T)(T* p) | ||
{ | ||
return p; // consumes owner | ||
} | ||
|
||
@live T* foo2(T)() | ||
{ | ||
T* p = null; | ||
return p; // consumes owner | ||
} | ||
|
||
@live T* foo3(T)(T* p) | ||
{ | ||
scope T* q = p; // borrows from p | ||
return p; // use of p ends borrow in q | ||
} | ||
|
||
@live T* foo4(T)(T* p) | ||
{ | ||
scope T* bq = p; // borrow | ||
scope const T* cq = p; // const borrow | ||
return p; // ends both borrows | ||
} | ||
|
||
@live T* foo5(T)() | ||
{ | ||
auto p = cast(T*) malloc(); | ||
scope b = p; | ||
return p; | ||
} | ||
|
||
void test() | ||
{ | ||
int* p; | ||
foo1!int(p); | ||
foo2!int(); | ||
foo3!int(p); | ||
foo4!int(p); | ||
foo5!int(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// REQUIRED_ARGS: -preview=dip1021 | ||
|
||
/* | ||
TEST_OUTPUT: | ||
--- | ||
fail_compilation/failob2.d(105): Error: variable `failob2.foo1!int.foo1.p` has undefined state and cannot be read | ||
fail_compilation/failob2.d(105): Error: variable `failob2.foo1!int.foo1.p` is returned but is Undefined | ||
fail_compilation/failob2.d(124): Error: template instance `failob2.foo1!int` error instantiating | ||
fail_compilation/failob2.d(111): Error: variable `failob2.foo2!int.foo2.p` has undefined state and cannot be read | ||
fail_compilation/failob2.d(111): Error: variable `failob2.foo2!int.foo2.p` is returned but is Undefined | ||
fail_compilation/failob2.d(125): Error: template instance `failob2.foo2!int` error instantiating | ||
fail_compilation/failob2.d(119): Error: variable `failob2.foo3!int.foo3.p` has undefined state and cannot be read | ||
fail_compilation/failob2.d(119): Error: variable `failob2.foo3!int.foo3.p` is returned but is Undefined | ||
fail_compilation/failob2.d(126): Error: template instance `failob2.foo3!int` error instantiating | ||
--- | ||
*/ | ||
|
||
#line 100 | ||
|
||
@live | ||
T* foo1(T)() | ||
{ | ||
T* p = void; | ||
return p; | ||
} | ||
|
||
template foo2(T) { | ||
@live T* foo2() { | ||
T* p = void; | ||
return p; | ||
} | ||
} | ||
|
||
@live | ||
template foo3(T) { | ||
T* foo3() { | ||
T* p = void; | ||
return p; | ||
} | ||
} | ||
|
||
void test1() { | ||
foo1!int(); | ||
foo2!int(); | ||
foo3!int(); | ||
} | ||
|
||
/* | ||
TEST_OUTPUT: | ||
--- | ||
fail_compilation/failob2.d(205): Error: variable `failob2.foo4!int.foo4.p` is left dangling at return | ||
fail_compilation/failob2.d(209): Error: template instance `failob2.foo4!int` error instantiating | ||
--- | ||
*/ | ||
|
||
#line 200 | ||
|
||
void* alloc(size_t); | ||
|
||
@live void foo4(T)() | ||
{ | ||
auto p = alloc(4); | ||
} | ||
|
||
void test2() { | ||
foo4!int(); | ||
} |