www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18029] New: extra dtor call with typed variadic argument (or


          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: nobody puremagic.com
          Reporter: ketmar 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);

void main () {
  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

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.

Dec 03 2017