diff --git a/include/boost/python/detail/caller.hpp b/include/boost/python/detail/caller.hpp index 1bd30bfb..557359f5 100644 --- a/include/boost/python/detail/caller.hpp +++ b/include/boost/python/detail/caller.hpp @@ -109,6 +109,23 @@ struct converter_target_type return 0; } }; + +// Generation of ret moved from caller_arity::impl::signature to here due to "feature" in MSVC 15.7.2 with /O2 +// which left the ret uninitialized and caused segfaults in Python interpreter. +template const signature_element* get_ret() +{ + typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type::type rtype; + typedef typename select_result_converter::type result_converter; + + static const signature_element ret = { + (is_void::value ? "void" : type_id().name()) + , &detail::converter_target_type::get_pytype + , boost::detail::indirect_traits::is_reference_to_non_const::value + }; + + return &ret; +}; + #endif @@ -229,16 +246,12 @@ struct caller_arity { const signature_element * sig = detail::signature::elements(); #ifndef BOOST_PYTHON_NO_PY_SIGNATURES + // MSVC 15.7.2, when compiling to /O2 left the static const signature_element ret, + // originally defined here, uninitialized. This in turn led to SegFault in Python interpreter. + // Issue is resolved by moving the generation of ret to separate function in detail namespace (see above). + const signature_element * ret = detail::get_ret(); - typedef BOOST_DEDUCED_TYPENAME Policies::template extract_return_type::type rtype; - typedef typename select_result_converter::type result_converter; - - static const signature_element ret = { - (is_void::value ? "void" : type_id().name()) - , &detail::converter_target_type::get_pytype - , boost::detail::indirect_traits::is_reference_to_non_const::value - }; - py_func_sig_info res = {sig, &ret }; + py_func_sig_info res = {sig, ret }; #else py_func_sig_info res = {sig, sig }; #endif diff --git a/include/boost/python/list.hpp b/include/boost/python/list.hpp index 10fd40fd..0d5e2c8f 100644 --- a/include/boost/python/list.hpp +++ b/include/boost/python/list.hpp @@ -73,7 +73,7 @@ class list : public detail::list_base } template - long count(T const& value) const + ssize_t count(T const& value) const { return base::count(object(value)); } diff --git a/src/object/function.cpp b/src/object/function.cpp index e612963b..9d4745d1 100644 --- a/src/object/function.cpp +++ b/src/object/function.cpp @@ -444,7 +444,9 @@ void function::add_to_namespace( if (dict == 0) throw_error_already_set(); + assert(!PyErr_Occurred()); handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr()))); + PyErr_Clear(); if (existing) { @@ -485,16 +487,15 @@ void function::add_to_namespace( if (new_func->name().is_none()) new_func->m_name = name; + assert(!PyErr_Occurred()); handle<> name_space_name( allow_null(::PyObject_GetAttrString(name_space.ptr(), const_cast("__name__")))); + PyErr_Clear(); if (name_space_name) new_func->m_namespace = object(name_space_name); } - // The PyObject_GetAttrString() or PyObject_GetItem calls above may - // have left an active error - PyErr_Clear(); if (PyObject_SetAttr(ns, name.ptr(), attribute.ptr()) < 0) throw_error_already_set();