mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-27 23:52:00 +00:00
Add workaround for clang 3.3/3.4
As reported in #1349, clang before 3.5 can segfault on a function-local variable referenced inside a lambda. This moves the function-local static into a separate function that the lambda can invoke to avoid the issue. Fixes #1349
This commit is contained in:
parent
6837740bb6
commit
97a62ebef2
@ -1631,6 +1631,7 @@ void register_exception_translator(ExceptionTranslator&& translator) {
|
|||||||
template <typename type>
|
template <typename type>
|
||||||
class exception : public object {
|
class exception : public object {
|
||||||
public:
|
public:
|
||||||
|
exception() = default;
|
||||||
exception(handle scope, const char *name, PyObject *base = PyExc_Exception) {
|
exception(handle scope, const char *name, PyObject *base = PyExc_Exception) {
|
||||||
std::string full_name = scope.attr("__name__").cast<std::string>() +
|
std::string full_name = scope.attr("__name__").cast<std::string>() +
|
||||||
std::string(".") + name;
|
std::string(".") + name;
|
||||||
@ -1647,6 +1648,14 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NAMESPACE_BEGIN(detail)
|
||||||
|
// Returns a reference to a function-local static exception object used in the simple
|
||||||
|
// register_exception approach below. (It would be simpler to have the static local variable
|
||||||
|
// directly in register_exception, but that makes clang <3.5 segfault - issue #1349).
|
||||||
|
template <typename CppException>
|
||||||
|
exception<CppException> &get_exception_object() { static exception<CppException> ex; return ex; }
|
||||||
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a Python exception in `m` of the given `name` and installs an exception translator to
|
* Registers a Python exception in `m` of the given `name` and installs an exception translator to
|
||||||
* translate the C++ exception to the created Python exception using the exceptions what() method.
|
* translate the C++ exception to the created Python exception using the exceptions what() method.
|
||||||
@ -1657,13 +1666,15 @@ template <typename CppException>
|
|||||||
exception<CppException> ®ister_exception(handle scope,
|
exception<CppException> ®ister_exception(handle scope,
|
||||||
const char *name,
|
const char *name,
|
||||||
PyObject *base = PyExc_Exception) {
|
PyObject *base = PyExc_Exception) {
|
||||||
static exception<CppException> ex(scope, name, base);
|
auto &ex = detail::get_exception_object<CppException>();
|
||||||
|
if (!ex) ex = exception<CppException>(scope, name, base);
|
||||||
|
|
||||||
register_exception_translator([](std::exception_ptr p) {
|
register_exception_translator([](std::exception_ptr p) {
|
||||||
if (!p) return;
|
if (!p) return;
|
||||||
try {
|
try {
|
||||||
std::rethrow_exception(p);
|
std::rethrow_exception(p);
|
||||||
} catch (const CppException &e) {
|
} catch (const CppException &e) {
|
||||||
ex(e.what());
|
detail::get_exception_object<CppException>()(e.what());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return ex;
|
return ex;
|
||||||
|
Loading…
Reference in New Issue
Block a user