mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
Throw an exception when attempting to load an incompatible holder
Instead of a segfault. Fixes #751. This covers the case of loading a custom holder from a default-holder instance. Attempting to load one custom holder from a different custom holder (i.e. not `std::unique_ptr`) yields undefined behavior, just as #588 established for inheritance.
This commit is contained in:
parent
0f5ec0a87e
commit
cd3d1fc7df
@ -919,6 +919,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeinfo->default_holder)
|
||||
throw cast_error("Unable to load a custom holder type from a default-holder instance");
|
||||
|
||||
if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */
|
||||
/* Check if we can safely perform a reinterpret-style cast */
|
||||
if (PyType_IsSubtype(tobj, typeinfo->type))
|
||||
|
@ -265,4 +265,10 @@ test_initializer smart_ptr_and_references([](py::module &pm) {
|
||||
|
||||
py::class_<C, CustomUniquePtr<C>>(m, "TypeWithMoveOnlyHolder")
|
||||
.def_static("make", []() { return CustomUniquePtr<C>(new C); });
|
||||
|
||||
struct HeldByDefaultHolder { };
|
||||
|
||||
py::class_<HeldByDefaultHolder>(m, "HeldByDefaultHolder")
|
||||
.def(py::init<>())
|
||||
.def_static("load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
|
||||
});
|
||||
|
@ -211,3 +211,12 @@ def test_move_only_holder():
|
||||
assert stats.alive() == 1
|
||||
del a
|
||||
assert stats.alive() == 0
|
||||
|
||||
|
||||
def test_smart_ptr_from_default():
|
||||
from pybind11_tests.smart_ptr import HeldByDefaultHolder
|
||||
|
||||
instance = HeldByDefaultHolder()
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
HeldByDefaultHolder.load_shared_ptr(instance)
|
||||
assert "Unable to load a custom holder type from a default-holder instance" in str(excinfo)
|
||||
|
Loading…
Reference in New Issue
Block a user