diff --git a/src/converter/type_id.cpp b/src/converter/type_id.cpp index c6a8bf7a04..4cdbe4194a 100644 --- a/src/converter/type_id.cpp +++ b/src/converter/type_id.cpp @@ -3,6 +3,7 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include @@ -18,9 +19,9 @@ #if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__ # include -#else +#else # include -#endif +#endif # ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE # if defined(__GNUC__) && __GNUC__ >= 3 @@ -34,7 +35,7 @@ class __class_type_info; # include # endif -# endif +# endif #endif /* defined(__QNXNTO__) */ namespace boost { namespace python { @@ -76,18 +77,31 @@ namespace return std::strcmp(x.first,y.first) < 0; } }; - + struct free_mem { free_mem(char*p) : p(p) {} - + ~free_mem() { std::free(p); } char* p; }; + + struct free_list + { + std::vector container; + + ~free_list() + { + BOOST_FOREACH(char * item, container) + { + free(item); + } + } + }; } bool cxxabi_cxa_demangle_is_broken() @@ -112,23 +126,25 @@ namespace detail typedef std::vector< std::pair > mangling_map; - + + static free_list demangler_free_mem; static mangling_map demangler; + mangling_map::iterator p = std::lower_bound( demangler.begin(), demangler.end() , std::make_pair(mangled, (char const*)0) , compare_first_cstring()); - + if (p == demangler.end() || strcmp(p->first, mangled)) { int status; free_mem keeper( cxxabi::__cxa_demangle(mangled, 0, 0, &status) ); - + assert(status != -3); // invalid argument error - + if (status == -1) { throw std::bad_alloc(); @@ -181,10 +197,17 @@ namespace detail } p = demangler.insert(p, std::make_pair(mangled, demangled)); - keeper.p = 0; + // We are keeping demangled reference. + // Transfer ownership to helper list that will free it + // on teardown. + if (keeper.p == demangled) + { + demangler_free_mem.container.push_back(keeper.p); + keeper.p = 0; + } } } - + return p->second; } } diff --git a/src/module.cpp b/src/module.cpp index 9628481996..6ed1ae7a80 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -21,7 +21,14 @@ namespace object m_obj(((borrowed_reference_t*)m)); scope current_module(m_obj); - handle_exception(init_function); + // If an exception happened we have to return NULL + if (handle_exception(init_function)) + { +#if PY_VERSION_HEX >= 0x03000000 + Py_DECREF(m); + m = 0; +#endif + } } return m;