#252 (['"[regression] no viable constructor for offset_ptr with clang from 1.87.0"])].

This commit is contained in:
Ion Gaztañaga
2026-01-04 15:43:56 +01:00
parent ab5e6c665d
commit e7bc830886
3 changed files with 48 additions and 11 deletions

View File

@@ -6866,6 +6866,7 @@ thank them:
* Fixed bugs:
* [@https://github.com/boostorg/interprocess/issues/242 GitHub #242 (['"Cygwin compatibility issues"])].
* [@https://github.com/boostorg/interprocess/issues/247 GitHub #247 (['"destruction of move-constructed map using private_adaptive_pool triggers Assertion"])].
* [@https://github.com/boostorg/interprocess/issues/252 GitHub #252 (['"[regression] no viable constructor for offset_ptr with clang from 1.87.0"])].
[endsect]

View File

@@ -251,6 +251,25 @@ namespace ipcdetail {
, Ret>
{};
template <class T, class P>
struct is_ptr_constructible;
template <class T, class P>
struct is_ptr_constructible<T*, P*>
{
private:
template<class U> static U get();
template <typename U>
static yes_type test( typename enable_if_c< sizeof( new U*(get<P*>()) ) != 0, int >::type );
template <typename U>
static no_type test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
};
} //namespace ipcdetail {
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
@@ -356,6 +375,20 @@ class offset_ptr
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
//!Constructor from other offset_ptr. Only takes part in overload resolution
//!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::move_detail::is_convertible<T2*, PointedType*>::value &&
ipcdetail::is_ptr_constructible<T2*, PointedType*>::value
>::type * = 0
#endif
) BOOST_NOEXCEPT
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
#endif
//!Emulates static_cast operator.

View File

@@ -411,24 +411,27 @@ void test_cast()
pcvvoid_t pcvvoid = pvoid;
pcvvoid = pvvoid;
//Test valid static_cast conversions
pint = static_pointer_cast<int>(pvoid);
pcint = static_pointer_cast<const int>(pcvoid);
pvint = static_pointer_cast<volatile int>(pvoid);
pcvint = static_pointer_cast<const volatile int>(pvoid);
//Test valid static_cast conversions required by Allocator::pointer
//requirements (void_pointer -> pointer, const_void_pointer -> const_pointer)
pint = static_cast<pint_t>(pvoid);
pcint = static_cast<pcint_t>(pcvoid);
BOOST_TEST(pint == pvoid);
BOOST_TEST(pcint == pint);
BOOST_TEST(pvint == pint);
BOOST_TEST(pcvint == pint);
//Test valid static_cast conversions
//Test valid static_pointer_cast conversions
{
pint = static_pointer_cast<int>(pvoid);
pcint = static_pointer_cast<const int>(pcvoid);
pvint = static_pointer_cast<volatile int>(pvoid);
pcvint = static_pointer_cast<const volatile int>(pvoid);
BOOST_TEST(pint == pvoid);
BOOST_TEST(pcint == pcvoid);
BOOST_TEST(pcint == pint);
BOOST_TEST(pvint == pint);
BOOST_TEST(pcvint == pint);
Derived d;
offset_ptr<Derived> pd(&d);
offset_ptr<Base> pb;
@@ -450,7 +453,7 @@ void test_cast()
BOOST_TEST(pb3.get() == static_cast<Base3*>(pd3.get()));
}
//Test valid const_cast conversions
//Test valid const_pointer_cast conversions
{
pint = const_pointer_cast<int>(pcint);
pint = const_pointer_cast<int>(pvint);
@@ -462,14 +465,14 @@ void test_cast()
pcint = const_pointer_cast<const int>(pvint);
pcint = const_pointer_cast<const int>(pcvint);
//Test valid reinterpret_cast conversions
//Test valid reinterpret_pointer_cast conversions
pint = reinterpret_pointer_cast<int>(pvoid);
pcint = reinterpret_pointer_cast<const int>(pcvoid);
pvint = reinterpret_pointer_cast<volatile int>(pvoid);
pcvint = reinterpret_pointer_cast<const volatile int>(pvoid);
}
//Test valid dynamic_cast conversions
//Test valid dynamic_pointer_cast conversions
{
{
Derived3 d3;