Skip to content

Commit b2fdfd1

Browse files
bzarcowjakob
authored andcommitted
Avoid use of lambda to work around a clang bug. (pybind#1883)
Clang has a bug [1] in x86 Windows that is exposed by the use of lambdas with "unforwardable" prototypes. The error is "error: cannot compile this forwarded non-trivially copyable parameter yet", and the message was introduced in [2] (used to be an assertion). [1] https://llvm.org/bugs/show_bug.cgi?id=28299 [2] checkedc/checkedc-clang@feb1567
1 parent bdf1a2c commit b2fdfd1

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

include/pybind11/detail/internals.h

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,34 @@ inline internals **&get_internals_pp() {
173173
return internals_pp;
174174
}
175175

176+
inline void translate_exception(std::exception_ptr p) {
177+
try {
178+
if (p) std::rethrow_exception(p);
179+
} catch (error_already_set &e) { e.restore(); return;
180+
} catch (const builtin_exception &e) { e.set_error(); return;
181+
} catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return;
182+
} catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
183+
} catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
184+
} catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
185+
} catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return;
186+
} catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
187+
} catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return;
188+
} catch (...) {
189+
PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!");
190+
return;
191+
}
192+
}
193+
194+
#if !defined(__GLIBCXX__)
195+
inline void translate_local_exception(std::exception_ptr p) {
196+
try {
197+
if (p) std::rethrow_exception(p);
198+
} catch (error_already_set &e) { e.restore(); return;
199+
} catch (const builtin_exception &e) { e.set_error(); return;
200+
}
201+
}
202+
#endif
203+
176204
/// Return a reference to the current `internals` data
177205
PYBIND11_NOINLINE inline internals &get_internals() {
178206
auto **&internals_pp = get_internals_pp();
@@ -198,15 +226,7 @@ PYBIND11_NOINLINE inline internals &get_internals() {
198226
//
199227
// libstdc++ doesn't require this (types there are identified only by name)
200228
#if !defined(__GLIBCXX__)
201-
(*internals_pp)->registered_exception_translators.push_front(
202-
[](std::exception_ptr p) -> void {
203-
try {
204-
if (p) std::rethrow_exception(p);
205-
} catch (error_already_set &e) { e.restore(); return;
206-
} catch (const builtin_exception &e) { e.set_error(); return;
207-
}
208-
}
209-
);
229+
(*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);
210230
#endif
211231
} else {
212232
if (!internals_pp) internals_pp = new internals*();
@@ -229,25 +249,7 @@ PYBIND11_NOINLINE inline internals &get_internals() {
229249
internals_ptr->istate = tstate->interp;
230250
#endif
231251
builtins[id] = capsule(internals_pp);
232-
internals_ptr->registered_exception_translators.push_front(
233-
[](std::exception_ptr p) -> void {
234-
try {
235-
if (p) std::rethrow_exception(p);
236-
} catch (error_already_set &e) { e.restore(); return;
237-
} catch (const builtin_exception &e) { e.set_error(); return;
238-
} catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return;
239-
} catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
240-
} catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
241-
} catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
242-
} catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return;
243-
} catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return;
244-
} catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return;
245-
} catch (...) {
246-
PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!");
247-
return;
248-
}
249-
}
250-
);
252+
internals_ptr->registered_exception_translators.push_front(&translate_exception);
251253
internals_ptr->static_property_type = make_static_property_type();
252254
internals_ptr->default_metaclass = make_default_metaclass();
253255
internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);

0 commit comments

Comments
 (0)