https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66139

            Bug ID: 66139
           Summary: destructor not called for members of partially
                    constructed anonymous struct/array
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: f.heckenb...@fh-soft.de
  Target Milestone: ---

The attached test program tries to construct various structures
consisting of two members of some type a, where construction of the
first one succeeds and the second one throws, and checks whether the
destructor of the first one was called before the exception is
caught.

Since the first member was constructed successfully, I'd expect its
destructor to be called. Granted, I don't know the exact standard
wording, but my general idea is that once a constructor call
succeeds, an object starts to exist, thus it must at some point
cease to exist, and then its destructor must be called. clang 3.5.0
and visual c++ (according to http://webcompiler.cloudapp.net/,
without the GCC extension "(a[2]) { ... }") do call the destructor
every time.

The g++ output is:

destructor called
destructor not called
destructor called
destructor not called
destructor not called
destructor not called

So with a named struct/array variable, the destructor gets called,
with anonymous ones it doesn't.

Even with a named initializer_list it doesn't, but I suppose that's
because the compiler first constructs an anonymous array (and then
would construct the initializer_list if it got there).

#include <iostream>

int c, d;

struct a
{
  a (int i) { if (i) throw i; c++; }
  ~a () { d++; }
};

void check (void (*f) ())
{
  try
  {
    c = d = 0;
    f ();
  }
  catch (int)
  {
    std::cerr << (c != 1 ? "constructor not completed exactly once\n" :
                  d == 0 ? "destructor not called\n" :
                  d == 1 ? "destructor called\n" :
                           "destructor called more than once\n");
    return;
  }
  std::cerr << "exception not thrown\n";
}

int main ()
{
  struct s { a x, y; };
  check ([] { s t { 0, 1 }; });
  check ([] { s { 0, 1 }; });
  check ([] { a t[2] { 0, 1 }; });
  check ([] { (a[2]) { 0, 1 }; });
  check ([] { std::initializer_list <a> t { 0, 1 }; });
  check ([] { std::initializer_list <a> { 0, 1 }; });
}

Reply via email to