diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 72b3a87fd..6effa1bc0 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -2037,7 +2037,7 @@ public: template enable_if_t::value, Return> call(Func &&f) && { - return std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); + return std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); // GET_INT_STACK -3 } template @@ -2065,7 +2065,7 @@ private: template Return call_impl(Func &&f, index_sequence, Guard &&) && { - return std::forward(f)(cast_op(std::move(std::get(argcasters)))...); + return std::forward(f)(cast_op(std::move(std::get(argcasters)))...); // GET_INT_STACK -2 } std::tuple...> argcasters; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 08c51c6f9..23599f214 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -56,6 +56,8 @@ # include #endif +#define TRIGGER_SEGSEV { unsigned long *bad = nullptr; *bad = -1; } + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object @@ -97,7 +99,7 @@ public: /// Construct a cpp_function from a class method (const, no ref-qualifier) template cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { - initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward(args)...); }, + initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward(args)...); }, // GET_INT_STACK -1 (Return (*)(const Class *, Arg ...)) nullptr, extra...); } @@ -167,7 +169,7 @@ protected: "The number of argument annotations does not match the number of function arguments"); /* Dispatch code which converts function arguments and performs the actual function call */ - rec->impl = [](function_call &call) -> handle { + rec->impl = [](function_call &call) -> handle { // GET_INT_STACK -5 cast_in args_converter; /* Try to cast the function arguments into the C++ domain */ @@ -190,7 +192,7 @@ protected: /* Perform the function call */ handle result = cast_out::cast( - std::move(args_converter).template call(cap->f), policy, call.parent); + std::move(args_converter).template call(cap->f), policy, call.parent); // GET_INT_STACK -4 /* Invoke call policy post-call hook */ process_attributes::postcall(call, result); @@ -552,7 +554,7 @@ protected: handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr, result = PYBIND11_TRY_NEXT_OVERLOAD; - auto self_value_and_holder = value_and_holder(); + auto self_value_and_holder = value_and_holder(); // cast.h if (overloads->is_constructor) { if (!PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) { PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument"); @@ -764,7 +766,7 @@ protected: // 6. Call the function. try { loader_life_support guard{}; - result = func.impl(call); + result = func.impl(call); // GET_INT_STACK -6 } catch (reference_cast_error &) { result = PYBIND11_TRY_NEXT_OVERLOAD; } @@ -930,7 +932,7 @@ protected: } else { if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) { auto *pi = reinterpret_cast(parent.ptr()); - self_value_and_holder.type->init_instance(pi, nullptr); + self_value_and_holder.type->init_instance(pi, nullptr); // GET_STACK -4 } return result.ptr(); } @@ -1536,7 +1538,7 @@ private: init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible()); v_h.set_holder_constructed(); } else if (inst->owned || detail::always_construct_holder::value) { - new (std::addressof(v_h.holder())) holder_type(v_h.value_ptr()); + new (std::addressof(v_h.holder())) holder_type(v_h.value_ptr()); // GET_STACK -2 v_h.set_holder_constructed(); } } @@ -1551,7 +1553,7 @@ private: register_instance(inst, v_h.value_ptr(), v_h.type); v_h.set_instance_registered(); } - init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr()); + init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr()); // GET_STACK -3 } /// Deallocates an instance; via holder, if constructed; otherwise via operator delete. diff --git a/include/pybind11/vptr_holder.h b/include/pybind11/vptr_holder.h index 39ef5206d..1de37adc8 100644 --- a/include/pybind11/vptr_holder.h +++ b/include/pybind11/vptr_holder.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -11,9 +12,12 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) // To enable passing of unique_ptr as in pure C++. template class vptr { public: - explicit vptr(T *ptr = nullptr) : vptr_{std::unique_ptr(ptr)} {} - explicit vptr(std::unique_ptr u) : vptr_{std::move(u)} {} - explicit vptr(std::shared_ptr s) : vptr_{s} {} + explicit vptr(T *ptr = nullptr) : vptr_{std::unique_ptr(ptr)} { + std::cout << std::endl << "explicit vptr(T *ptr = nullptr)" << std::endl; + //TRIGGER_SEGSEV + } + explicit vptr(std::unique_ptr u) : vptr_{std::move(u)} { std::cout << std::endl << "explicit vptr(std::unique_ptr u)" << std::endl; } + explicit vptr(std::shared_ptr s) : vptr_{s} { std::cout << std::endl << "explicit vptr(std::shared_ptr s)" << std::endl; } int ownership_type() const { if (std::get_if<0>(&vptr_)) { @@ -26,6 +30,7 @@ template class vptr { } T *get() { + std::cout << std::endl << "vptr::get" << std::endl; auto u = std::get_if<0>(&vptr_); if (u) { return u->get(); @@ -64,7 +69,7 @@ template class vptr { }; template class vptr_holder : public vptr { - using vptr::vptr; + using vptr::vptr; // GET_STACK -1 }; PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/tests/test_unique_ptr_member.cpp b/tests/test_unique_ptr_member.cpp index 38a99a679..ebe5e09ee 100644 --- a/tests/test_unique_ptr_member.cpp +++ b/tests/test_unique_ptr_member.cpp @@ -16,6 +16,7 @@ class pointee { // NOT copyable. int get_int() const { to_cout("pointee::get_int()"); + //TRIGGER_SEGSEV return 213; } diff --git a/tests/work.py b/tests/work.py new file mode 100644 index 000000000..11dd213b4 --- /dev/null +++ b/tests/work.py @@ -0,0 +1,12 @@ +from pybind11_tests import unique_ptr_member as m + + +def test_pointee_and_ptr_owner(): + m.to_cout("") + obj = m.pointee() + assert obj.get_int() == 213 + del obj + print("DONE.", flush=True) + + +test_pointee_and_ptr_owner()