2

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.

trbabb
  • 1,894
  • 18
  • 35

0 Answers0