Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 4fd4fa3

Browse files
authored
Merge pull request #2366 from radcapricorn/fix11294
Fix Issue 11294 - Object destruction with alias this merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
2 parents 7438796 + 3b9c093 commit 4fd4fa3

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

src/object.d

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,15 +576,18 @@ nothrow @safe @nogc unittest
576576
/// ditto
577577
void destroy(T)(T obj) if (is(T == class))
578578
{
579+
// go through void** to avoid `alias this` preferring alias
580+
// this should not be necessary when @@@BUG6777@@@ is fixed
581+
auto ptr = () @trusted { return *cast(void**) &obj; } ();
579582
static if (__traits(getLinkage, T) == "C++")
580583
{
581584
obj.__xdtor();
582585

583586
enum classSize = __traits(classInstanceSize, T);
584-
(cast(void*)obj)[0 .. classSize] = typeid(T).initializer[];
587+
ptr[0 .. classSize] = typeid(T).initializer[];
585588
}
586589
else
587-
rt_finalize(cast(void*)obj);
590+
rt_finalize(ptr);
588591
}
589592

590593
/// ditto
@@ -671,6 +674,40 @@ nothrow @safe @nogc unittest
671674
assert(i == 0); // `i` is back to its initial state `0`
672675
}
673676

677+
unittest
678+
{
679+
// class with an `alias this`
680+
class A
681+
{
682+
static int dtorCount;
683+
~this()
684+
{
685+
dtorCount++;
686+
}
687+
}
688+
689+
class B
690+
{
691+
A a;
692+
alias a this;
693+
this()
694+
{
695+
a = new A;
696+
}
697+
static int dtorCount;
698+
~this()
699+
{
700+
dtorCount++;
701+
}
702+
}
703+
auto b = new B;
704+
assert(A.dtorCount == 0);
705+
assert(B.dtorCount == 0);
706+
destroy(b);
707+
assert(A.dtorCount == 0);
708+
assert(B.dtorCount == 1);
709+
}
710+
674711
unittest
675712
{
676713
interface I { }

0 commit comments

Comments
 (0)