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.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.