@@ -586,25 +586,11 @@ class type_caster_generic {
586
586
return inst.release ();
587
587
}
588
588
589
- // Base methods for generic caster; there are overridden in copyable_holder_caster
589
+ // Base methods for generic caster; they are overridden in copyable_holder_caster
590
590
void load_value (value_and_holder &&v_h) {
591
- auto *&vptr = v_h.value_ptr ();
592
- // Lazy allocation for unallocated values:
593
- if (vptr == nullptr ) {
594
- auto *type = v_h.type ? v_h.type : typeinfo;
595
- if (type->operator_new ) {
596
- vptr = type->operator_new (type->type_size );
597
- } else {
598
- #if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
599
- if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
600
- vptr = ::operator new (type->type_size ,
601
- std::align_val_t (type->type_align ));
602
- else
603
- #endif
604
- vptr = ::operator new (type->type_size );
605
- }
606
- }
607
- value = vptr;
591
+ value = v_h.value_ptr ();
592
+ if (value == nullptr )
593
+ throw cast_error (" Invalid object instance" );
608
594
}
609
595
bool try_implicit_casts (handle src, bool convert) {
610
596
for (auto &cast : typeinfo->implicit_casts ) {
@@ -1581,7 +1567,7 @@ struct move_only_holder_caster : public type_caster_base<type> {
1581
1567
bool load (handle& src, bool convert) {
1582
1568
bool success = base::template load_impl<move_only_holder_caster<type, holder_type>>(src, convert);
1583
1569
if (success) // On success, remember src pointer to withdraw later
1584
- src_handle = std::addressof (src);
1570
+ this -> v_h = reinterpret_cast <instance *> (src. ptr ())-> get_value_and_holder ( );
1585
1571
return success;
1586
1572
}
1587
1573
@@ -1593,6 +1579,10 @@ struct move_only_holder_caster : public type_caster_base<type> {
1593
1579
explicit
1594
1580
#endif
1595
1581
operator holder_type&&() {
1582
+ // In load_value() value_ptr was still valid. If it's invalid now, another argument consumed the same value before.
1583
+ if (!v_h.value_ptr ())
1584
+ throw cast_error (" Multiple access to moved argument" );
1585
+ v_h.value_ptr () = nullptr ;
1596
1586
// TODO: release object instance in python
1597
1587
// clear_instance(src_handle->ptr()); ???
1598
1588
@@ -1615,6 +1605,8 @@ struct move_only_holder_caster : public type_caster_base<type> {
1615
1605
if (v_h.holder_constructed ()) {
1616
1606
holder_ptr = std::addressof (v_h.template holder <holder_type>());
1617
1607
value = const_cast <void *>(reinterpret_cast <const void *>(holder_helper<holder_type>::get (*holder_ptr)));
1608
+ if (!value)
1609
+ throw cast_error (" Invalid object instance" );
1618
1610
return true ;
1619
1611
} else {
1620
1612
throw cast_error (" Unable to cast from non-held to held instance (T& to Holder<T>) "
@@ -1636,7 +1628,7 @@ struct move_only_holder_caster : public type_caster_base<type> {
1636
1628
1637
1629
1638
1630
holder_type* holder_ptr = nullptr ;
1639
- handle* src_handle = nullptr ;
1631
+ value_and_holder v_h ;
1640
1632
};
1641
1633
1642
1634
template <typename type, typename deleter>
0 commit comments