Skip to content

Commit 900177a

Browse files
committed
Fixes #272 ("Regression boost 1.87: offset_ptr conversion from void no longer works")
1 parent e56a371 commit 900177a

File tree

3 files changed

+173
-17
lines changed

3 files changed

+173
-17
lines changed

doc/interprocess.qbk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6781,6 +6781,7 @@ thank them:
67816781
* Fixed bugs:
67826782
* [@https://github.com/boostorg/interprocess/pull/245 GitHub #245 (['"Fix UBSan runtime error (load of 'boost::interprocess::mode_t')"])].
67836783
* [@https://github.com/boostorg/interprocess/pull/269 GitHub #269 (['"Minor documentation fixes and template parameter renames"])].
6784+
* [@https://github.com/boostorg/interprocess/issues/272 GitHub #272 (['"Regression boost 1.87: offset_ptr conversion from void no longer works"])].
67846785

67856786
[endsect]
67866787

include/boost/interprocess/offset_ptr.hpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -681,38 +681,38 @@ inline std::basic_istream<E, T> & operator>>
681681
{ return is >> p.get_offset(); }
682682

683683
//!Simulation of static_cast between pointers. Never throws.
684-
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
685-
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
686-
static_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
684+
template<class T1, class P, class O, std::size_t A, class T2>
685+
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P, O, A>
686+
static_pointer_cast(const boost::interprocess::offset_ptr<T2, P, O, A> & r) BOOST_NOEXCEPT
687687
{
688-
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
688+
return boost::interprocess::offset_ptr<T1, P, O, A>
689689
(r, boost::interprocess::ipcdetail::static_cast_tag());
690690
}
691691

692692
//!Simulation of const_cast between pointers. Never throws.
693-
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
694-
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
695-
const_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
693+
template<class T1, class P, class O, std::size_t A, class T2>
694+
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P, O, A>
695+
const_pointer_cast(const boost::interprocess::offset_ptr<T2, P, O, A> & r) BOOST_NOEXCEPT
696696
{
697-
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
697+
return boost::interprocess::offset_ptr<T1, P, O, A>
698698
(r, boost::interprocess::ipcdetail::const_cast_tag());
699699
}
700700

701701
//!Simulation of dynamic_cast between pointers. Never throws.
702-
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
703-
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
704-
dynamic_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
702+
template<class T1, class P, class O, std::size_t A, class T2>
703+
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P, O, A>
704+
dynamic_pointer_cast(const boost::interprocess::offset_ptr<T2, P, O, A> & r) BOOST_NOEXCEPT
705705
{
706-
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
706+
return boost::interprocess::offset_ptr<T1, P, O, A>
707707
(r, boost::interprocess::ipcdetail::dynamic_cast_tag());
708708
}
709709

710710
//!Simulation of reinterpret_cast between pointers. Never throws.
711-
template<class T1, class P1, class O1, std::size_t A1, class T2, class P2, class O2, std::size_t A2>
712-
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P1, O1, A1>
713-
reinterpret_pointer_cast(const boost::interprocess::offset_ptr<T2, P2, O2, A2> & r) BOOST_NOEXCEPT
711+
template<class T1, class P, class O, std::size_t A, class T2>
712+
BOOST_INTERPROCESS_FORCEINLINE boost::interprocess::offset_ptr<T1, P, O, A>
713+
reinterpret_pointer_cast(const boost::interprocess::offset_ptr<T2, P, O, A> & r) BOOST_NOEXCEPT
714714
{
715-
return boost::interprocess::offset_ptr<T1, P1, O1, A1>
715+
return boost::interprocess::offset_ptr<T1, P, O, A>
716716
(r, boost::interprocess::ipcdetail::reinterpret_cast_tag());
717717
}
718718

test/offset_ptr_test.cpp

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,48 @@
1616
using namespace boost::interprocess;
1717

1818
class Base
19-
{};
19+
{
20+
int padding;
21+
public:
22+
Base() : padding(0){}
23+
int *get() { return &padding; }
24+
virtual ~Base(){}
25+
};
26+
27+
class Base2
28+
{
29+
int padding;
30+
public:
31+
Base2() : padding(0){}
32+
int *get() { return &padding; }
33+
virtual ~Base2(){}
34+
};
35+
36+
class Base3
37+
{
38+
int padding;
39+
public:
40+
Base3() : padding(0){}
41+
int *get() { return &padding; }
42+
virtual ~Base3(){}
43+
};
2044

2145
class Derived
2246
: public Base
2347
{};
2448

49+
class Derived3
50+
: public Base, public Base2, public Base3
51+
{};
52+
2553
class VirtualDerived
2654
: public virtual Base
2755
{};
2856

57+
class VirtualDerived3
58+
: public virtual Base, public virtual Base2, public virtual Base3
59+
{};
60+
2961
void test_types_and_conversions()
3062
{
3163
typedef offset_ptr<int> pint_t;
@@ -355,6 +387,128 @@ void test_pointer_plus_bits()
355387
BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == 0);
356388
}
357389

390+
void test_cast()
391+
{
392+
typedef offset_ptr<int> pint_t;
393+
typedef offset_ptr<const int> pcint_t;
394+
typedef offset_ptr<volatile int> pvint_t;
395+
typedef offset_ptr<const volatile int> pcvint_t;
396+
typedef offset_ptr<void> pvoid_t;
397+
typedef offset_ptr<const void> pcvoid_t;
398+
typedef offset_ptr<volatile void> pvvoid_t;
399+
typedef offset_ptr<const volatile void> pcvvoid_t;
400+
401+
int dummy_int = 9;
402+
403+
{ pint_t pint(&dummy_int);
404+
pcint_t pcint(pint);
405+
pvint_t pvint = pint;
406+
pcvint_t pcvint = pvint;
407+
408+
pvoid_t pvoid = pint;
409+
pcvoid_t pcvoid = pvoid;
410+
pvvoid_t pvvoid = pvoid;
411+
pcvvoid_t pcvvoid = pvoid;
412+
pcvvoid = pvvoid;
413+
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);
419+
420+
BOOST_TEST(pint == pvoid);
421+
BOOST_TEST(pcint == pint);
422+
BOOST_TEST(pvint == pint);
423+
BOOST_TEST(pcvint == pint);
424+
425+
//Test valid static_cast conversions
426+
{
427+
pint = static_pointer_cast<int>(pvoid);
428+
pcint = static_pointer_cast<const int>(pcvoid);
429+
pvint = static_pointer_cast<volatile int>(pvoid);
430+
pcvint = static_pointer_cast<const volatile int>(pvoid);
431+
432+
Derived d;
433+
offset_ptr<Derived> pd(&d);
434+
offset_ptr<Base> pb;
435+
//Downcast
436+
pb = static_pointer_cast<Base>(pd);
437+
//Upcast
438+
pd = static_pointer_cast<Derived>(pb);
439+
440+
Derived3 d3;
441+
offset_ptr<Derived3> pd3(&d3);
442+
offset_ptr<Base3> pb3;
443+
444+
//Downcast
445+
pb3 = static_pointer_cast<Base3>(pd3);
446+
//Upcast
447+
pd3 = static_pointer_cast<Derived3>(pb3);
448+
//Test addresses don't match in multiple inheritance
449+
BOOST_TEST((pvoid_t)pb3 != (pvoid_t)pd3);
450+
BOOST_TEST(pb3.get() == static_cast<Base3*>(pd3.get()));
451+
}
452+
453+
//Test valid const_cast conversions
454+
{
455+
pint = const_pointer_cast<int>(pcint);
456+
pint = const_pointer_cast<int>(pvint);
457+
pint = const_pointer_cast<int>(pcvint);
458+
459+
pvint = const_pointer_cast<volatile int>(pcint);
460+
pvint = const_pointer_cast<volatile int>(pcvint);
461+
462+
pcint = const_pointer_cast<const int>(pvint);
463+
pcint = const_pointer_cast<const int>(pcvint);
464+
465+
//Test valid reinterpret_cast conversions
466+
pint = reinterpret_pointer_cast<int>(pvoid);
467+
pcint = reinterpret_pointer_cast<const int>(pcvoid);
468+
pvint = reinterpret_pointer_cast<volatile int>(pvoid);
469+
pcvint = reinterpret_pointer_cast<const volatile int>(pvoid);
470+
}
471+
472+
//Test valid dynamic_cast conversions
473+
{
474+
{
475+
Derived3 d3;
476+
offset_ptr<Derived3> pd3(&d3);
477+
offset_ptr<Base2> pb2;
478+
479+
//Downcast
480+
pb2 = dynamic_pointer_cast<Base2>(pd3);
481+
//Upcast
482+
pd3 = dynamic_pointer_cast<Derived3>(pb2);
483+
BOOST_TEST((pvoid_t)pb2 != (pvoid_t)pd3);
484+
BOOST_TEST(pb2.get() == dynamic_cast<Base2*>(&d3));
485+
BOOST_TEST(static_cast<void*>(pb2.get()) != static_cast<void*>(pd3.get()));
486+
}
487+
{
488+
VirtualDerived3 vd3;
489+
offset_ptr<VirtualDerived3> pdv3(&vd3);
490+
offset_ptr<Base3> pb3;
491+
offset_ptr<Base2> pb2;
492+
offset_ptr<Base> pb;
493+
494+
//Downcast
495+
pb3 = dynamic_pointer_cast<Base3>(pdv3);
496+
pb2 = dynamic_pointer_cast<Base2>(pdv3);
497+
pb = dynamic_pointer_cast<Base> (pdv3);
498+
//Upcast
499+
pdv3 = dynamic_pointer_cast<VirtualDerived3>(pb);
500+
pdv3 = dynamic_pointer_cast<VirtualDerived3>(pb2);
501+
pdv3 = dynamic_pointer_cast<VirtualDerived3>(pb3);
502+
//Test addresses don't match in multiple inheritance
503+
BOOST_TEST((pvoid_t)pb2 != (pvoid_t)pdv3);
504+
BOOST_TEST(pb2.get() != static_cast<void*>(pdv3.get()));
505+
BOOST_TEST((pvoid_t)pb3 != (pvoid_t)pdv3);
506+
BOOST_TEST(pb3.get() != static_cast<void*>(pdv3.get()));
507+
}
508+
}
509+
}
510+
}
511+
358512
int main()
359513
{
360514
test_types_and_conversions();
@@ -363,5 +517,6 @@ int main()
363517
test_comparison();
364518
test_pointer_traits();
365519
test_pointer_plus_bits();
520+
test_cast();
366521
return ::boost::report_errors();
367522
}

0 commit comments

Comments
 (0)