interprocess icon indicating copy to clipboard operation
interprocess copied to clipboard

[regression] no viable constructor for offset_ptr with clang from 1.87.0

Open wanghan02 opened this issue 11 months ago • 1 comments

Example code could be found as below or on godbolt. The example compiles fine with VS/gcc + boost 1.87.0 or clang + boost 1.86.0. It fails with clang + boost 1.87.0.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <map>

using namespace boost::interprocess;

managed_shared_memory g_segment(create_only, "shared", 65536);

template<typename T>
struct shared_allocator: allocator<T, managed_shared_memory::segment_manager>
{
    using base_=allocator<T, managed_shared_memory::segment_manager>;
    
    shared_allocator(): base_(g_segment.get_segment_manager()) {}

    template<typename U>
    struct rebind final {
        using other = shared_allocator<U>;
    };
};

std::map<int, int, std::less<int>, shared_allocator<std::pair<int const, int>>> mapnn;

wanghan02 avatar Mar 03 '25 09:03 wanghan02

It seems that the constructor was deleted in this commit.

 //!Constructor from other offset_ptr. Only takes part in overload resolution 1Has a conversation.
   //!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
   template<class T2>
   BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
             #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
             , typename ipcdetail::enable_if_c<
                !::boost::is_convertible<T2*, PointedType*>::value && ::boost::is_constructible<T2*, PointedType*>::value
             >::type * = 0
             #endif
             ) BOOST_NOEXCEPT
      : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
   {}

wanghan02 avatar Mar 05 '25 10:03 wanghan02

Here's another case which fails with all the major compilers:

This change makes allocators using this pointer (like adaptive_pool) no longer meet the requirements of Allocator since it is no longer possible to cast std::allocator_traits<A>::void_pointer to std::allocator_traits<A>::pointer.

Godbolt

gharveymn avatar Apr 13 '25 00:04 gharveymn