Skip to content

Commit e7bc830

Browse files
committed
#252 (['"[regression] no viable constructor for offset_ptr with clang from 1.87.0"])].
1 parent ab5e6c6 commit e7bc830

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

doc/interprocess.qbk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6866,6 +6866,7 @@ thank them:
68666866
* Fixed bugs:
68676867
* [@https://github.com/boostorg/interprocess/issues/242 GitHub #242 (['"Cygwin compatibility issues"])].
68686868
* [@https://github.com/boostorg/interprocess/issues/247 GitHub #247 (['"destruction of move-constructed map using private_adaptive_pool triggers Assertion"])].
6869+
* [@https://github.com/boostorg/interprocess/issues/252 GitHub #252 (['"[regression] no viable constructor for offset_ptr with clang from 1.87.0"])].
68696870

68706871
[endsect]
68716872

include/boost/interprocess/offset_ptr.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,25 @@ namespace ipcdetail {
251251
, Ret>
252252
{};
253253

254+
template <class T, class P>
255+
struct is_ptr_constructible;
256+
257+
template <class T, class P>
258+
struct is_ptr_constructible<T*, P*>
259+
{
260+
private:
261+
template<class U> static U get();
262+
263+
template <typename U>
264+
static yes_type test( typename enable_if_c< sizeof( new U*(get<P*>()) ) != 0, int >::type );
265+
266+
template <typename U>
267+
static no_type test(...);
268+
269+
public:
270+
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
271+
};
272+
254273
} //namespace ipcdetail {
255274
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
256275

@@ -356,6 +375,20 @@ class offset_ptr
356375
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
357376
{}
358377

378+
//!Constructor from other offset_ptr. Only takes part in overload resolution
379+
//!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
380+
template<class T2>
381+
BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
382+
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
383+
, typename ipcdetail::enable_if_c<
384+
!::boost::move_detail::is_convertible<T2*, PointedType*>::value &&
385+
ipcdetail::is_ptr_constructible<T2*, PointedType*>::value
386+
>::type * = 0
387+
#endif
388+
) BOOST_NOEXCEPT
389+
: internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
390+
{}
391+
359392
#endif
360393

361394
//!Emulates static_cast operator.

test/offset_ptr_test.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -411,24 +411,27 @@ void test_cast()
411411
pcvvoid_t pcvvoid = pvoid;
412412
pcvvoid = pvvoid;
413413

414-
//Test valid static_cast conversions
415-
pint = static_pointer_cast<int>(pvoid);
416-
pcint = static_pointer_cast<const int>(pcvoid);
417-
pvint = static_pointer_cast<volatile int>(pvoid);
418-
pcvint = static_pointer_cast<const volatile int>(pvoid);
414+
//Test valid static_cast conversions required by Allocator::pointer
415+
//requirements (void_pointer -> pointer, const_void_pointer -> const_pointer)
416+
pint = static_cast<pint_t>(pvoid);
417+
pcint = static_cast<pcint_t>(pcvoid);
419418

420419
BOOST_TEST(pint == pvoid);
421420
BOOST_TEST(pcint == pint);
422-
BOOST_TEST(pvint == pint);
423-
BOOST_TEST(pcvint == pint);
424421

425-
//Test valid static_cast conversions
422+
//Test valid static_pointer_cast conversions
426423
{
427424
pint = static_pointer_cast<int>(pvoid);
428425
pcint = static_pointer_cast<const int>(pcvoid);
429426
pvint = static_pointer_cast<volatile int>(pvoid);
430427
pcvint = static_pointer_cast<const volatile int>(pvoid);
431428

429+
BOOST_TEST(pint == pvoid);
430+
BOOST_TEST(pcint == pcvoid);
431+
BOOST_TEST(pcint == pint);
432+
BOOST_TEST(pvint == pint);
433+
BOOST_TEST(pcvint == pint);
434+
432435
Derived d;
433436
offset_ptr<Derived> pd(&d);
434437
offset_ptr<Base> pb;
@@ -450,7 +453,7 @@ void test_cast()
450453
BOOST_TEST(pb3.get() == static_cast<Base3*>(pd3.get()));
451454
}
452455

453-
//Test valid const_cast conversions
456+
//Test valid const_pointer_cast conversions
454457
{
455458
pint = const_pointer_cast<int>(pcint);
456459
pint = const_pointer_cast<int>(pvint);
@@ -462,14 +465,14 @@ void test_cast()
462465
pcint = const_pointer_cast<const int>(pvint);
463466
pcint = const_pointer_cast<const int>(pcvint);
464467

465-
//Test valid reinterpret_cast conversions
468+
//Test valid reinterpret_pointer_cast conversions
466469
pint = reinterpret_pointer_cast<int>(pvoid);
467470
pcint = reinterpret_pointer_cast<const int>(pcvoid);
468471
pvint = reinterpret_pointer_cast<volatile int>(pvoid);
469472
pcvint = reinterpret_pointer_cast<const volatile int>(pvoid);
470473
}
471474

472-
//Test valid dynamic_cast conversions
475+
//Test valid dynamic_pointer_cast conversions
473476
{
474477
{
475478
Derived3 d3;

0 commit comments

Comments
 (0)