This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-07-18 14:15:12 -07:00
parent 516811642e
commit 31e8ac562f

View File

@ -92,32 +92,40 @@ inline void type_caster_odr_guard_impl(const std::type_info &intrinsic_type_info
} }
} }
struct tu_local_no_data_always_false_base {
explicit operator bool() const noexcept { return false; }
};
namespace { // WARNING: This creates an ODR violation in the ODR guard itself, namespace { // WARNING: This creates an ODR violation in the ODR guard itself,
// but we do not have anything better at the moment. // but we do not have anything better at the moment.
// The ODR violation here does not involve any data at all. // The ODR violation here does not involve any data at all.
// See also: Comment near top of descr.h & WARNING in descr.h // See also: Comment near top of descr.h & WARNING in descr.h
struct tu_local_no_data_always_false { struct tu_local_no_data_always_false : tu_local_no_data_always_false_base {
explicit operator bool() const noexcept { return false; } explicit tu_local_no_data_always_false(const std::type_info &intrinsic_type_info,
const src_loc &sloc,
bool throw_disabled) {
type_caster_odr_guard_impl(intrinsic_type_info, sloc, throw_disabled);
}
}; };
} // namespace } // namespace
template <typename IntrinsicType, typename TypeCasterType> template <typename IntrinsicType, typename TypeCasterType>
struct type_caster_odr_guard : TypeCasterType { struct type_caster_odr_guard : TypeCasterType {
static tu_local_no_data_always_false translation_unit_local; static tu_local_no_data_always_false_base *translation_unit_local;
type_caster_odr_guard() { type_caster_odr_guard() {
// Possibly, good optimizers will elide this `if` (and below) completely. // Possibly, good optimizers will elide this `if` (and below) completely.
// It is needed only to trigger the TU-local mechanisms. // It is needed only to trigger the TU-local mechanisms.
if (translation_unit_local) { if (*translation_unit_local) {
} }
} }
// The original author of this function is @amauryfa // The original author of this function is @amauryfa
template <typename CType, typename... Arg> template <typename CType, typename... Arg>
static handle cast(CType &&src, return_value_policy policy, handle parent, Arg &&...arg) { static handle cast(CType &&src, return_value_policy policy, handle parent, Arg &&...arg) {
if (translation_unit_local) { if (*translation_unit_local) {
} }
return TypeCasterType::cast( return TypeCasterType::cast(
std::forward<CType>(src), policy, parent, std::forward<Arg>(arg)...); std::forward<CType>(src), policy, parent, std::forward<Arg>(arg)...);
@ -125,16 +133,11 @@ struct type_caster_odr_guard : TypeCasterType {
}; };
template <typename IntrinsicType, typename TypeCasterType> template <typename IntrinsicType, typename TypeCasterType>
tu_local_no_data_always_false tu_local_no_data_always_false_base*
type_caster_odr_guard<IntrinsicType, TypeCasterType>::translation_unit_local type_caster_odr_guard<IntrinsicType, TypeCasterType>::translation_unit_local = []() {
= []() { return new tu_local_no_data_always_false(typeid(IntrinsicType),
// Executed only once per process (e.g. when a PYBIND11_MODULE is initialized).
// Conclusively tested vi test_type_caster_odr_guard_1, test_type_caster_odr_guard_2:
// those tests will fail if the sloc here is not working as intended (TU-local).
type_caster_odr_guard_impl(typeid(IntrinsicType),
TypeCasterType::name.sloc, TypeCasterType::name.sloc,
PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_THROW_DISABLED); PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_THROW_DISABLED);
return tu_local_no_data_always_false();
}(); }();
PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(detail)