From d4b989f4409a3872338abd35606ff3dffe3b7092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Ferreira?= Date: Mon, 15 Feb 2021 22:09:30 +0000 Subject: [PATCH] Fix issue #21640: @live not working with templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luís Ferreira --- src/dmd/mtype.d | 1 + test/compilable/ob2.d | 44 ++++++++++++++++++++++ test/fail_compilation/failob2.d | 67 +++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 test/compilable/ob2.d create mode 100644 test/fail_compilation/failob2.d diff --git a/src/dmd/mtype.d b/src/dmd/mtype.d index a5ee8c3d8cef..f6a1ae27877a 100644 --- a/src/dmd/mtype.d +++ b/src/dmd/mtype.d @@ -4267,6 +4267,7 @@ extern (C++) final class TypeFunction : TypeNext t.mod = mod; t.isnothrow = isnothrow; t.isnogc = isnogc; + t.islive = islive; t.purity = purity; t.isproperty = isproperty; t.isref = isref; diff --git a/test/compilable/ob2.d b/test/compilable/ob2.d new file mode 100644 index 000000000000..ec7c6663e40e --- /dev/null +++ b/test/compilable/ob2.d @@ -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(); +} diff --git a/test/fail_compilation/failob2.d b/test/fail_compilation/failob2.d new file mode 100644 index 000000000000..bd5264854092 --- /dev/null +++ b/test/fail_compilation/failob2.d @@ -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(); +}