[libcxx-dev] Possible bug in std::allocate_shared implementation

Eric Christopher via libcxx-dev libcxx-dev at lists.llvm.org
Wed May 15 14:35:45 PDT 2019


Typically it's better to report bugs on the bug tracker.

-eric

On Wed, May 15, 2019 at 2:30 PM Laurent Pinchart via libcxx-dev
<libcxx-dev at lists.llvm.org> wrote:
>
> Hello,
>
> Was it wrong to report the issue below on the mailing list, should I
> have requested a bug tracker account and reported it there ? As I'm not
> 100% confident that this is a libc++ bug I was hoping to get feedback
> here before requesting a bug tracker (as self-registration is disabled
> due to spam).
>
> On Mon, Apr 29, 2019 at 12:28:01PM +0300, Laurent Pinchart wrote:
> > Hello,
> >
> > 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();
> >
> > My limited knowledge of libc++ internals and of C++ compilers in general
> > prevents me from proposing a fix. I would appreciate if someone could
> > first confirm that the test case is valid, and then hopefully help :-)
>
> --
> Regards,
>
> Laurent Pinchart
> _______________________________________________
> libcxx-dev mailing list
> libcxx-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev


More information about the libcxx-dev mailing list