http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50793

             Bug #: 50793
           Summary: G++ doesn't value-initialize all members of
                    non-trivial type in default argument
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: r...@gcc.gnu.org
                CC: ja...@gcc.gnu.org


struct NonTrivial
{
    NonTrivial() { }
};

struct S
{
    NonTrivial nt;
    int i;
};

int f(S s = S())
{
    s.i = 0xdeadbeef;
    return s.i;
}

int g(S s = S())
{
    return s.i;
}

int main()
{
    f();  // make stack dirty

    if ( g() )
        __builtin_abort();
}

This should not abort, the default argument of g() should be value-initialized,
which means:

C++03) if T is a non-union class type without a user-declared constructor, then
every non-static data member and base-class component of T is
value-initialized;

C++11) if T is a (possibly cv-qualified) non-union class type without a
user-provided constructor, then the object is zero-initialized and, if T’s
implicitly-declared default constructor is non-trivial, that constructor is
called.


If the implicitly-declared constructor S::S() is trivial, then S::i is
zero-initialized as expected.  When S::S() is non-trivial,
NonTrivial::NonTrivial() is called correctly, but S::i is not zero-initialized.

N.B. the test does not fail if the default argument uses list-init, S{}


This was identified by my -Wmeminit patch for PR 2972 which identified 
uninitialized data when doing:

  std::vector<S> v;
  v.resize(1);

Reply via email to