Skip to content

Commit 31e8ac5

Browse files
committed
WIP
1 parent 5168116 commit 31e8ac5

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

include/pybind11/detail/type_caster_odr_guard.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,49 +92,52 @@ inline void type_caster_odr_guard_impl(const std::type_info &intrinsic_type_info
9292
}
9393
}
9494

95+
struct tu_local_no_data_always_false_base {
96+
explicit operator bool() const noexcept { return false; }
97+
};
98+
9599
namespace { // WARNING: This creates an ODR violation in the ODR guard itself,
96100
// but we do not have anything better at the moment.
97101
// The ODR violation here does not involve any data at all.
98102
// See also: Comment near top of descr.h & WARNING in descr.h
99103

100-
struct tu_local_no_data_always_false {
101-
explicit operator bool() const noexcept { return false; }
104+
struct tu_local_no_data_always_false : tu_local_no_data_always_false_base {
105+
explicit tu_local_no_data_always_false(const std::type_info &intrinsic_type_info,
106+
const src_loc &sloc,
107+
bool throw_disabled) {
108+
type_caster_odr_guard_impl(intrinsic_type_info, sloc, throw_disabled);
109+
}
102110
};
103111

104112
} // namespace
105113

106114
template <typename IntrinsicType, typename TypeCasterType>
107115
struct type_caster_odr_guard : TypeCasterType {
108-
static tu_local_no_data_always_false translation_unit_local;
116+
static tu_local_no_data_always_false_base *translation_unit_local;
109117

110118
type_caster_odr_guard() {
111119
// Possibly, good optimizers will elide this `if` (and below) completely.
112120
// It is needed only to trigger the TU-local mechanisms.
113-
if (translation_unit_local) {
121+
if (*translation_unit_local) {
114122
}
115123
}
116124

117125
// The original author of this function is @amauryfa
118126
template <typename CType, typename... Arg>
119127
static handle cast(CType &&src, return_value_policy policy, handle parent, Arg &&...arg) {
120-
if (translation_unit_local) {
128+
if (*translation_unit_local) {
121129
}
122130
return TypeCasterType::cast(
123131
std::forward<CType>(src), policy, parent, std::forward<Arg>(arg)...);
124132
}
125133
};
126134

127135
template <typename IntrinsicType, typename TypeCasterType>
128-
tu_local_no_data_always_false
129-
type_caster_odr_guard<IntrinsicType, TypeCasterType>::translation_unit_local
130-
= []() {
131-
// Executed only once per process (e.g. when a PYBIND11_MODULE is initialized).
132-
// Conclusively tested vi test_type_caster_odr_guard_1, test_type_caster_odr_guard_2:
133-
// those tests will fail if the sloc here is not working as intended (TU-local).
134-
type_caster_odr_guard_impl(typeid(IntrinsicType),
136+
tu_local_no_data_always_false_base*
137+
type_caster_odr_guard<IntrinsicType, TypeCasterType>::translation_unit_local = []() {
138+
return new tu_local_no_data_always_false(typeid(IntrinsicType),
135139
TypeCasterType::name.sloc,
136140
PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_THROW_DISABLED);
137-
return tu_local_no_data_always_false();
138141
}();
139142

140143
PYBIND11_NAMESPACE_END(detail)

0 commit comments

Comments
 (0)