<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - std::allocate_shared can't allocate object with private constructor"
   href="https://bugs.llvm.org/show_bug.cgi?id=41900">41900</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::allocate_shared can't allocate object with private constructor
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>8.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>laurent.pinchart@ideasonboard.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I ran into what I believe can be a bug in the libc++ implementation of
std::allocate_shared<>. The following code fails to compile due to two
issues.

------------------------------------------------------------------------
#include <memory>

class Private;

class Factory {
public:
        static std::shared_ptr<Private> allocate();
};

class Private {
private:
        friend class Factory;
        Private() { }
        ~Private() { }
};

std::shared_ptr<Private> Factory::allocate()
{
        struct Allocator : std::allocator<Private> {
                void construct(void *p)
                {
                        ::new(p) Private();
                }
                void destroy(Private *p)
                {
                        p->~Private();
                }
        };

        return std::allocate_shared<Private>(Allocator());
}
------------------------------------------------------------------------

First of all, commit 7700912976a5 ("Land D28253 which fixes PR28929
(which we mistakenly marked as fixed before)") introduced a static
assert to verify that the object type is constructible:

static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object
in allocate_shared" );

This fails, as Private is not constructible in the context of the
std::allocate_shared<> implementations, due to its private constructor
and destructor. I believe that the check is incorrect, as I don't see
anything in the C++ standard that mandates the object type to be
constructible by std::allocate_shared<> itself.

I tried removing the static asserts, and that's where the real fun
began. If my understanding is correct, in order to store the pointed
data, libc++ uses an internal __shared_ptr_emplace<_Tp, _Alloc> class
that contains (through a few levels of inheritance) an instance of _Tp.
That class has its destructor implicitly deleted due to the private
nature of ~Private(). The compiler then complains about

/usr/include/c++/v1/memory:3604:7: error: deleted function
'~__shared_ptr_emplace' cannot override a non-deleted function
class __shared_ptr_emplace
[...]
/usr/include/c++/v1/memory:3513:13: note: overridden virtual function is here
    virtual ~__shared_weak_count();</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>