Skip to content

Commit 83bc8d2

Browse files
committed
final_virtual_ptr: add sanity checks
1 parent ba6d178 commit 83bc8d2

File tree

5 files changed

+162
-131
lines changed

5 files changed

+162
-131
lines changed

include/boost/openmethod/core.hpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,13 @@ inline auto final_virtual_ptr(Arg&& obj) {
578578
using Traits = virtual_traits<Arg, Registry>;
579579
using Class = typename Traits::virtual_type;
580580

581+
static_assert(!std::is_const_v<Class>);
582+
static_assert(!std::is_volatile_v<Class>);
583+
static_assert(!std::is_reference_v<Class>);
584+
static_assert(!std::is_pointer_v<Class>);
585+
586+
Registry::require_initialized();
587+
581588
if constexpr (
582589
Registry::has_runtime_checks &&
583590
Registry::rtti::template is_polymorphic<Class>) {
@@ -598,10 +605,12 @@ inline auto final_virtual_ptr(Arg&& obj) {
598605
}
599606
}
600607

608+
const vptr_type& vptr = Registry::template static_vptr<Class>;
609+
BOOST_ASSERT(vptr);
610+
601611
return VirtualPtr(
602612
std::forward<Arg>(obj),
603-
detail::box_vptr<VirtualPtr::use_indirect_vptrs>(
604-
Registry::template static_vptr<Class>));
613+
detail::box_vptr<VirtualPtr::use_indirect_vptrs>(vptr));
605614
}
606615

607616
//! Create a `virtual_ptr` for an object of a known dynamic type.
@@ -610,12 +619,13 @@ inline auto final_virtual_ptr(Arg&& obj) {
610619
//! registry as the `Registry` template parameter.
611620
//!
612621
//! @see @ref final_virtual_ptr
622+
// We could give a default value to Registry in the main template, but gcc
623+
// doesn't like it.
613624
template<class Arg>
614625
inline auto final_virtual_ptr(Arg&& obj) {
615626
return final_virtual_ptr<BOOST_OPENMETHOD_DEFAULT_REGISTRY, Arg>(
616627
std::forward<Arg>(obj));
617628
}
618-
619629
//! Wide pointer combining pointers to an object and its v-table
620630
//!
621631
//! A `virtual_ptr` is a wide pointer that combines pointers to an object and

test/test_shared_virtual_ptr_value_semantics.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
258258
}
259259

260260
{
261-
auto p = make_shared_virtual<Dog>();
261+
auto p = make_shared_virtual<Dog, Registry>();
262262
p = nullptr;
263263
BOOST_TEST(p.get() == nullptr);
264264
BOOST_TEST(p.vptr() == nullptr);
265265
}
266266

267267
{
268-
auto p = make_shared_virtual<Dog>();
268+
auto p = make_shared_virtual<Dog, Registry>();
269269
p = std::shared_ptr<Dog>();
270270
BOOST_TEST(p.get() == nullptr);
271271
BOOST_TEST(p.vptr() == nullptr);
@@ -278,13 +278,17 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
278278
}
279279

280280
BOOST_AUTO_TEST_CASE(cast_shared_ptr_value) {
281+
init_test<default_registry>();
282+
281283
std::shared_ptr<Animal> animal = std::make_shared<Dog>();
282284
auto dog = virtual_traits<std::shared_ptr<Animal>, default_registry>::cast<
283285
std::shared_ptr<Dog>>(animal);
284286
BOOST_TEST(dog.get() == animal.get());
285287
}
286288

287289
BOOST_AUTO_TEST_CASE(cast_shared_ptr_lvalue_reference) {
290+
init_test<default_registry>();
291+
288292
std::shared_ptr<Animal> animal = std::make_shared<Dog>();
289293
auto dog =
290294
virtual_traits<const std::shared_ptr<Animal>&, default_registry>::cast<
@@ -293,13 +297,17 @@ BOOST_AUTO_TEST_CASE(cast_shared_ptr_lvalue_reference) {
293297
}
294298

295299
bool cast_moves() {
300+
init_test<default_registry>();
301+
296302
std::shared_ptr<Animal> animal = std::make_shared<Dog>();
297303
(void)std::static_pointer_cast<Dog>(animal);
298304

299305
return animal.get() == nullptr;
300306
}
301307

302308
BOOST_AUTO_TEST_CASE(cast_shared_ptr_xvalue_reference) {
309+
init_test<default_registry>();
310+
303311
std::shared_ptr<Animal> animal = std::make_shared<Dog>();
304312
auto p = animal.get();
305313
auto dog = virtual_traits<std::shared_ptr<Animal>, default_registry>::cast<
@@ -313,6 +321,8 @@ BOOST_AUTO_TEST_CASE(cast_shared_ptr_xvalue_reference) {
313321

314322
BOOST_AUTO_TEST_CASE_TEMPLATE(
315323
cast_shared_virtual_ptr_value, Class, test_classes) {
324+
init_test<default_registry>();
325+
316326
shared_virtual_ptr<Animal> base = make_shared_virtual<Class>();
317327
auto derived =
318328
virtual_traits<shared_virtual_ptr<Animal>, default_registry>::cast<
@@ -324,6 +334,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
324334

325335
BOOST_AUTO_TEST_CASE_TEMPLATE(
326336
cast_shared_virtual_ptr_lvalue_reference, Class, test_classes) {
337+
init_test<default_registry>();
338+
327339
shared_virtual_ptr<Animal> base = make_shared_virtual<Class>();
328340
auto derived =
329341
virtual_traits<const shared_virtual_ptr<Animal>&, default_registry>::
@@ -335,6 +347,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
335347

336348
BOOST_AUTO_TEST_CASE_TEMPLATE(
337349
cast_shared_virtual_ptr_xvalue_reference, Class, test_classes) {
350+
init_test<default_registry>();
351+
338352
shared_virtual_ptr<Animal> base = make_shared_virtual<Class>();
339353
auto p = base.get();
340354
auto derived =

test/test_unique_virtual_ptr_value_semantics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,13 +260,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(
260260

261261
BOOST_AUTO_TEST_CASE_TEMPLATE(
262262
cast_unique_virtual_ptr_value, Class, test_classes) {
263+
init_test<default_registry>();
264+
263265
unique_virtual_ptr<Animal> base = make_unique_virtual<Class>();
264266
auto p = base.get();
265267
auto derived =
266268
virtual_traits<unique_virtual_ptr<Animal>, default_registry>::cast<
267269
unique_virtual_ptr<Class>>(std::move(base));
268270
BOOST_TEST(derived.get() == p);
269-
BOOST_TEST(derived.vptr() == default_registry::static_vptr<Dog>);
271+
BOOST_TEST(derived.vptr() == default_registry::static_vptr<Class>);
270272
BOOST_TEST(base.get() == nullptr);
271273
}
272274

0 commit comments

Comments
 (0)