Skip to content

Avoid std::type_info pointer comparison #914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,17 @@ struct type_record {
/// Is the default (unique_ptr) holder type used?
bool default_holder : 1;

PYBIND11_NOINLINE void add_base(const std::type_info *base, void *(*caster)(void *)) {
auto base_info = detail::get_type_info(*base, false);
PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) {
auto base_info = detail::get_type_info(base, false);
if (!base_info) {
std::string tname(base->name());
std::string tname(base.name());
detail::clean_type_id(tname);
pybind11_fail("generic_type: type \"" + std::string(name) +
"\" referenced unknown base type \"" + tname + "\"");
}

if (default_holder != base_info->default_holder) {
std::string tname(base->name());
std::string tname(base.name());
detail::clean_type_id(tname);
pybind11_fail("generic_type: type \"" + std::string(name) + "\" " +
(default_holder ? "does not have" : "has") +
Expand Down Expand Up @@ -384,7 +384,7 @@ struct process_attribute<T, enable_if_t<is_pyobject<T>::value>> : process_attrib
/// Process a parent class attribute (deprecated, does not support multiple inheritance)
template <typename T>
struct process_attribute<base<T>> : process_attribute_default<base<T>> {
static void init(const base<T> &, type_record *r) { r->add_base(&typeid(T), nullptr); }
static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
};

/// Process a multiple inheritance attribute
Expand Down
14 changes: 7 additions & 7 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,14 +646,14 @@ class type_caster_generic {
// isn't needed or can't be used. If the type is unknown, sets the error and returns a pair
// with .second = nullptr. (p.first = nullptr is not an error: it becomes None).
PYBIND11_NOINLINE static std::pair<const void *, const type_info *> src_and_type(
const void *src, const std::type_info *cast_type, const std::type_info *rtti_type = nullptr) {
const void *src, const std::type_info &cast_type, const std::type_info *rtti_type = nullptr) {
auto &internals = get_internals();
auto it = internals.registered_types_cpp.find(std::type_index(*cast_type));
auto it = internals.registered_types_cpp.find(std::type_index(cast_type));
if (it != internals.registered_types_cpp.end())
return {src, (const type_info *) it->second};

// Not found, set error:
std::string tname = (rtti_type ? rtti_type : cast_type)->name();
std::string tname = rtti_type ? rtti_type->name() : cast_type.name();
detail::clean_type_id(tname);
std::string msg = "Unregistered type : " + tname;
PyErr_SetString(PyExc_TypeError, msg.c_str());
Expand Down Expand Up @@ -730,11 +730,11 @@ template <typename type> class type_caster_base : public type_caster_generic {
static std::pair<const void *, const type_info *> src_and_type(const itype *src) {
const void *vsrc = src;
auto &internals = get_internals();
auto cast_type = &typeid(itype);
auto &cast_type = typeid(itype);
const std::type_info *instance_type = nullptr;
if (vsrc) {
instance_type = &typeid(*src);
if (instance_type != cast_type) {
if (*instance_type != cast_type) {
// This is a base pointer to a derived type; if it is a pybind11-registered type, we
// can get the correct derived pointer (which may be != base pointer) by a
// dynamic_cast to most derived type:
Expand All @@ -751,7 +751,7 @@ template <typename type> class type_caster_base : public type_caster_generic {
// Non-polymorphic type, so no dynamic casting; just call the generic version directly
template <typename T = itype, enable_if_t<!std::is_polymorphic<T>::value, int> = 0>
static std::pair<const void *, const type_info *> src_and_type(const itype *src) {
return type_caster_generic::src_and_type(src, &typeid(itype));
return type_caster_generic::src_and_type(src, typeid(itype));
}

static handle cast(const itype *src, return_value_policy policy, handle parent) {
Expand Down Expand Up @@ -1700,7 +1700,7 @@ constexpr arg operator"" _a(const char *name, size_t) { return arg(name); }

NAMESPACE_BEGIN(detail)

// forward declaration
// forward declaration (definition in attr.h)
struct function_record;

/// Internal data associated with a single function call
Expand Down
3 changes: 2 additions & 1 deletion include/pybind11/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ struct type_caster<std::function<Return(Args...)>> {
auto c = reinterpret_borrow<capsule>(PyCFunction_GET_SELF(cfunc.ptr()));
auto rec = (function_record *) c;

if (rec && rec->is_stateless && rec->data[1] == &typeid(function_type)) {
if (rec && rec->is_stateless &&
typeid(function_type) == *reinterpret_cast<const std::type_info *>(rec->data[1])) {
struct capture { function_type f; };
value = ((capture *) &rec->data)->f;
return true;
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ class class_ : public detail::generic_type {

template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0>
static void add_base(detail::type_record &rec) {
rec.add_base(&typeid(Base), [](void *src) -> void * {
rec.add_base(typeid(Base), [](void *src) -> void * {
return static_cast<Base *>(reinterpret_cast<type *>(src));
});
}
Expand Down