Skip to content

Commit e2aa4ec

Browse files
committed
Replace global map holders_seen with local holder_type in registered type_info
1 parent 6360006 commit e2aa4ec

File tree

4 files changed

+11
-4
lines changed

4 files changed

+11
-4
lines changed

include/pybind11/attr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ struct type_record {
238238
/// What is the alignment of the underlying C++ type?
239239
size_t type_align = 0;
240240

241+
// Pointer to RTTI type_info data structure of holder type
242+
const std::type_info *holder_type = nullptr;
243+
241244
/// How large is the type's holder?
242245
size_t holder_size = 0;
243246

include/pybind11/cast.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,14 +1496,16 @@ void check_for_holder_mismatch_impl() {
14961496
using iholder = intrinsic_t<holder>;
14971497
using base_type = decltype(*holder_helper<iholder>::get(std::declval<iholder>()));
14981498
auto &holder_typeinfo = typeid(iholder);
1499-
auto ins = get_internals().holders_seen.emplace(typeid(base_type), &holder_typeinfo);
1499+
auto base_info = detail::get_type_info(typeid(base_type));
1500+
if (!base_info)
1501+
return; // Don't complain if we see this type the first time
15001502

15011503
auto debug = type_id<base_type>();
1502-
if (!ins.second && !same_type(*ins.first->second, holder_typeinfo)) {
1504+
if (!same_type(*base_info->holder_type, holder_typeinfo)) {
15031505
#ifdef NDEBUG
15041506
pybind11_fail("Mismatched holders detected (compile in debug mode for details)");
15051507
#else
1506-
std::string seen_holder_name(ins.first->second->name());
1508+
std::string seen_holder_name(base_info->holder_type->name());
15071509
detail::clean_type_id(seen_holder_name);
15081510
pybind11_fail("Mismatched holders detected: "
15091511
" attempting to use holder type " + type_id<iholder>() + ", but " + type_id<base_type>() +

include/pybind11/detail/internals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ struct internals {
9797
type_map<type_info *> registered_types_cpp; // std::type_index -> pybind11's type information
9898
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s)
9999
std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance*
100-
type_map<const std::type_info *> holders_seen; // type -> seen holder type (to detect holder conflicts)
101100
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash> inactive_override_cache;
102101
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
103102
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
@@ -129,6 +128,7 @@ struct internals {
129128
struct type_info {
130129
PyTypeObject *type;
131130
const std::type_info *cpptype;
131+
const std::type_info *holder_type = nullptr;
132132
size_t type_size, type_align, holder_size_in_ptrs;
133133
void *(*operator_new)(size_t);
134134
void (*init_instance)(instance *, const void *);

include/pybind11/pybind11.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,7 @@ class generic_type : public object {
10451045
auto *tinfo = new detail::type_info();
10461046
tinfo->type = (PyTypeObject *) m_ptr;
10471047
tinfo->cpptype = rec.type;
1048+
tinfo->holder_type = rec.holder_type;
10481049
tinfo->type_size = rec.type_size;
10491050
tinfo->type_align = rec.type_align;
10501051
tinfo->operator_new = rec.operator_new;
@@ -1233,6 +1234,7 @@ class class_ : public detail::generic_type {
12331234
record.type = &typeid(type);
12341235
record.type_size = sizeof(conditional_t<has_alias, type_alias, type>);
12351236
record.type_align = alignof(conditional_t<has_alias, type_alias, type>&);
1237+
record.holder_type = &typeid(holder_type);
12361238
record.holder_size = sizeof(holder_type);
12371239
record.init_instance = init_instance;
12381240
record.dealloc = dealloc;

0 commit comments

Comments
 (0)