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

            Bug ID: 87704
           Summary: [6/7/8/9 Regression] unique_ptr<T>(nullptr_t) requires
                    T to be complete
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

#include <memory>

struct Incomplete;

void f(void* p)
{
  ::new (p) std::unique_ptr<Incomplete>();              // OK

  ::new (p) std::unique_ptr<Incomplete>(nullptr);       // ERROR
}

This fails because the unique_ptr(nullptr_t) constructor is implemented
precisely as specified in C++11 and C++14:

  constexpr unique_ptr(nullptr_t) noexcept
    : unique_ptr() { }

The use of a delegating constructor means that the destructor is odr-used which
invokes default_delete<T>::operator() which is ill-formed if T is incomplete.

The example compiled until r194651 but fails in all versions since 4.8.0

The same problem exists for the unique_ptr<T[], D> specialization, but not for
shared_ptr(nullptr) because that doesn't create a control block so doesn't
instantiate a deleter.

Reply via email to