https://issues.dlang.org/show_bug.cgi?id=18029
Issue ID: 18029 Summary: extra dtor call with typed variadic argument (or missing postblit) Product: D Version: D2 Hardware: x86 OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ket...@ketmar.no-ip.org the following code failing the assertion: === int rc = 0; struct S { int n; this (int na) { ++rc; n = na; import core.stdc.stdio; printf("ctor for (n=%d)\n", n); } this (this) { if (n) ++rc; import core.stdc.stdio; printf("postblit for (n=%d)\n", n); } ~this () { if (n) --rc; import core.stdc.stdio; printf("dtor for (n=%d)\n", n); n = 0; } } void test0 (S[] vals...) { vals[0] = S.init; //(1) this causes the bug } void test1 () { auto a0 = S(1); test0(a0); } void main () { test1(); assert(rc == 0); } === `dtor for (n=1)` is called twice, but only if (1) is not commented. comment out (1), and the bug is gone. *technically* calling dtor on already destructed struct is not a bug. but IRL it will ruin any reference counting scheme. tbh, i don't know how to fix this... let's say "corner case" without loosing performance. also, i dont' know why `a0` isn't cleared by `vals[0] = S.init;`. i thought that typed vararg just creates a slice of program stack, and assigning `.init` to `vals` member should clear `a0`. either that, or compiler should call postblit for each typed vararg member (please, no! ;-). so, this can be "missing postblit call" case too. i put both in subj until we'll decide what should be done in this case. please note that i'm clearing `n` in dtor, so calling dtor on already "destroyed" struct should not be disasterous. but somehow `a0` is not cleared. --