From bf050c18e780920e45e28aa4b1ec32e54513b976 Mon Sep 17 00:00:00 2001 From: Teodor Dutu Date: Wed, 1 Dec 2021 19:46:58 +0200 Subject: [PATCH 1/3] Translate _d_delstruct to template Signed-off-by: Teodor Dutu --- src/core/lifetime.d | 70 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/core/lifetime.d b/src/core/lifetime.d index d4452d1c94..c0a3537a0c 100644 --- a/src/core/lifetime.d +++ b/src/core/lifetime.d @@ -1,6 +1,7 @@ module core.lifetime; import core.internal.attributes : betterC; +import core.memory; // emplace /** @@ -2221,3 +2222,72 @@ pure nothrow @nogc @system unittest static assert(!__traits(compiles, f(ncarray))); f(move(ncarray)); } + +/** + * This is called for a delete statement where the value + * being deleted is a pointer to a struct with a destructor + * but doesn't have an overloaded delete operator. + * + * Param: + * p = pointer to the value to be deleted + */ +void _d_delstruct(T)(ref T *p) +{ + if (p) + { + debug(PRINTF) printf("_d_delstruct(%p)\n", p); + + destroy(*p); + GC.free(p); + p = null; + } +} + +unittest +{ + int dtors = 0; + struct S { ~this() { ++dtors; } } + + S *s = new S(); + _d_delstruct(s); + + assert(s == null); + assert(dtors == 1); +} + +unittest +{ + int innerDtors = 0; + int outerDtors = 0; + + struct Inner { ~this() { ++innerDtors; } } + struct Outer + { + Inner *i1; + Inner *i2; + + this(int x) + { + i1 = new Inner(); + i2 = new Inner(); + } + + ~this() + { + ++outerDtors; + + _d_delstruct(i1); + assert(i1 == null); + + _d_delstruct(i2); + assert(i2 == null); + } + } + + Outer *o = new Outer(0); + _d_delstruct(o); + + assert(o == null); + assert(innerDtors == 2); + assert(outerDtors == 1); +} From 38865fcb1f47530feb68a20c83a5415f45e41e4a Mon Sep 17 00:00:00 2001 From: Teodor Dutu Date: Wed, 1 Dec 2021 21:06:02 +0200 Subject: [PATCH 2/3] _d_delstruct: Add @system to unittests Signed-off-by: Teodor Dutu --- src/core/lifetime.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lifetime.d b/src/core/lifetime.d index c0a3537a0c..452dbf1de7 100644 --- a/src/core/lifetime.d +++ b/src/core/lifetime.d @@ -1,7 +1,7 @@ module core.lifetime; import core.internal.attributes : betterC; -import core.memory; +import core.memory : GC; // emplace /** @@ -2243,7 +2243,7 @@ void _d_delstruct(T)(ref T *p) } } -unittest +@system unittest { int dtors = 0; struct S { ~this() { ++dtors; } } @@ -2255,7 +2255,7 @@ unittest assert(dtors == 1); } -unittest +@system unittest { int innerDtors = 0; int outerDtors = 0; From f6cf2c8d26313971220335e95b6c0bfe5af84542 Mon Sep 17 00:00:00 2001 From: Teodor Dutu Date: Thu, 2 Dec 2021 17:34:57 +0200 Subject: [PATCH 3/3] Import _d_delstruct in object.d Signed-off-by: Teodor Dutu --- src/core/lifetime.d | 5 +++-- src/object.d | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/lifetime.d b/src/core/lifetime.d index 452dbf1de7..b45e95f422 100644 --- a/src/core/lifetime.d +++ b/src/core/lifetime.d @@ -1,7 +1,6 @@ module core.lifetime; import core.internal.attributes : betterC; -import core.memory : GC; // emplace /** @@ -2228,7 +2227,7 @@ pure nothrow @nogc @system unittest * being deleted is a pointer to a struct with a destructor * but doesn't have an overloaded delete operator. * - * Param: + * Params: * p = pointer to the value to be deleted */ void _d_delstruct(T)(ref T *p) @@ -2237,6 +2236,8 @@ void _d_delstruct(T)(ref T *p) { debug(PRINTF) printf("_d_delstruct(%p)\n", p); + import core.memory : GC; + destroy(*p); GC.free(p); p = null; diff --git a/src/object.d b/src/object.d index 3360eb92e8..95fb6eccd3 100644 --- a/src/object.d +++ b/src/object.d @@ -4637,6 +4637,8 @@ public import core.internal.array.construction : _d_arrayctor; public import core.internal.array.construction : _d_arraysetctor; public import core.internal.array.capacity: _d_arraysetlengthTImpl; +public import core.lifetime : _d_delstruct; + public import core.internal.dassert: _d_assert_fail; public import core.internal.destruction: __ArrayDtor;