mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 16:13:53 +00:00
Additional demonstration of Undefined Behavior in handling of shared_ptr holder.
This commit is contained in:
parent
bda49efb14
commit
9623045b7b
@ -3,8 +3,12 @@
|
||||
// https://github.com/pybind/pybind11/blob/30eb39ed79d1e2eeff15219ac00773034300a5e6/include/pybind11/cast.h#L235
|
||||
// `return reinterpret_cast<H &>(vh[1]);`
|
||||
// indirectly casts a `shared_ptr<drvd>` reference to a `shared_ptr<base>`.
|
||||
// `test_smart_ptr_private_first_base.py` fails with an AssertionError and
|
||||
// a subsequent Segmentation Fault (Linux, clang++ -std=c++17).
|
||||
// Similarly:
|
||||
// https://github.com/pybind/pybind11/blob/30eb39ed79d1e2eeff15219ac00773034300a5e6/include/pybind11/pybind11.h#L1505
|
||||
// `init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());`
|
||||
// explictly casts a `shared_ptr<base>` reference to a `shared_ptr<drvd>`.
|
||||
// Both tests in `test_smart_ptr_private_first_base.py` fail with a
|
||||
// Segmentation Fault (Linux, clang++ -std=c++17).
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -33,14 +37,21 @@ inline std::shared_ptr<drvd> make_shared_drvd() {
|
||||
return std::shared_ptr<drvd>(new drvd);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<base> make_shared_drvd_up_cast() {
|
||||
return std::shared_ptr<base>(new drvd);
|
||||
}
|
||||
|
||||
inline int pass_shared_base(std::shared_ptr<base> b) { return b->id(); }
|
||||
inline int pass_shared_drvd(std::shared_ptr<drvd> d) { return d->id(); }
|
||||
|
||||
TEST_SUBMODULE(smart_ptr_private_first_base, m) {
|
||||
py::class_<base, std::shared_ptr<base>>(m, "base");
|
||||
py::class_<drvd, base, std::shared_ptr<drvd>>(m, "drvd");
|
||||
|
||||
m.def("make_shared_drvd", make_shared_drvd);
|
||||
m.def("make_shared_drvd_up_cast", make_shared_drvd_up_cast);
|
||||
m.def("pass_shared_base", pass_shared_base);
|
||||
m.def("pass_shared_drvd", pass_shared_drvd);
|
||||
}
|
||||
|
||||
} // namespace smart_ptr_private_first_base
|
||||
|
@ -3,7 +3,16 @@ import pytest
|
||||
|
||||
from pybind11_tests import smart_ptr_private_first_base as m
|
||||
|
||||
def test_make_pass():
|
||||
|
||||
def test_make_drvd_pass_base():
|
||||
d = m.make_shared_drvd()
|
||||
i = m.pass_shared_base(d)
|
||||
assert i == 200
|
||||
|
||||
|
||||
def test_make_drvd_up_cast_pass_drvd():
|
||||
b = m.make_shared_drvd_up_cast()
|
||||
# the base return is up-cast immediately.
|
||||
assert b.__class__.__name__ == "drvd"
|
||||
i = m.pass_shared_drvd(b)
|
||||
assert i == 200
|
||||
|
Loading…
Reference in New Issue
Block a user