I have a function which returns an llvm::Value*
, which I would like to expose to Python. I do not need to expose an interface to llvm::Value
; it can be an opaque object in Python.
When I call the function, I get a crash. (I'll provide the stack below). If I instead wrap the pointer in a trivial struct with an auto_ptr
, there is no crash. I am running MacOS X and compiling with the darwin-gcc toolchain.
Here's the code:
#include <boost/python.hpp>
#include <memory>
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
namespace python = boost::python;
struct Wrapper {
std::auto_ptr<llvm::Value> val;
Wrapper(llvm::Value* val):val(val) {}
};
llvm::Value* getValue() {
llvm::Value* v = llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(2.5));
v->dump();
return v;
}
Wrapper* getWrapper() {
llvm::Value* v = llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(3.5));
v->dump();
return new Wrapper(v);
}
BOOST_PYTHON_MODULE(TestCase) {
// functions
// (note that the same issue still persists if
// return_value_policy is reference_existing_object).
python::def("getValue", &getValue, python::return_value_policy<python::manage_new_object>());
python::def("getWrapper", &getWrapper, python::return_value_policy<python::manage_new_object>());
// classes
python::class_< llvm::Value, boost::noncopyable >("LLVMValue", python::no_init);
python::class_< Wrapper, boost::noncopyable >("Wrapper", python::no_init);
}
Invoked:
import TestCase
# no crash:
z = TestCase.getWrapper()
# crash:
y = TestCase.getValue()
And the stack:
0 libc++abi.dylib 0x00007fff919cb78a __cxxabiv1::__si_class_type_info::has_unambiguous_public_base(__cxxabiv1::__dynamic_cast_info*, void*, int) const + 0
1 libstdc++.6.dylib 0x000000010df5294b __dynamic_cast + 104
2 TestCase.so 0x000000010bad66be _object* boost::python::detail::wrapper_base_::owner_impl<llvm::Value>(llvm::Value const volatile*, mpl_::bool_<true>) + 57 (wrapper_base.hpp:64)
3 TestCase.so 0x000000010bad6487 _object* boost::python::detail::wrapper_base_::owner<llvm::Value>(llvm::Value const volatile*) + 29 (wrapper_base.hpp:37)
4 TestCase.so 0x000000010bad63a0 _object* boost::python::to_python_indirect<llvm::Value*, boost::python::detail::make_owning_holder>::execute<llvm::Value>(llvm::Value const&, mpl_::bool_<false>) const + 36 (to_python_indirect.hpp:67)
...
Am I misusing boost::python
? Is this a bug? Why does this crash? I would prefer not return wrappers everywhere, as that requires intrusive changes to the C++ API.