gdb/python: allow ref_ptr<T, Policy>::new_reference to accept subclasses of T

When ref_ptr<T,Policy>::new_reference() is specialized for 'PyObject'
(i.e. gdbpy_ref<>), it currently requires the argument type to be exactly
'PyObject *'. As a result, pointers to subclasses of 'PyObject' must be
explicitly cast before being passed, making call sites unnecessarily
verbose.

This patch makes ref_ptr<T,Policy>::new_reference() a template method
that accepts both T and subclasses of T, performing the cast to 'T *'
internally when needed. This removes redundant casts at call sites
without changing behavior.

Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
Matthieu Longo 2026-02-26 17:20:20 +00:00
parent 995cf2f8fe
commit f0cfbf6ced
3 changed files with 6 additions and 3 deletions

View file

@ -346,7 +346,7 @@ block_to_block_object (const struct block *block, struct objfile *objfile)
block_object *result = (block_object *) htab_find_with_hash (table, block,
hash);
if (result != nullptr)
return gdbpy_ref<>::new_reference ((PyObject *) result);
return gdbpy_ref<>::new_reference (result);
result = PyObject_New (block_object, &block_object_type);
if (result == nullptr)

View file

@ -400,7 +400,7 @@ infpy_threads (PyObject *self, PyObject *args)
for (const thread_map_t::value_type &entry : *inf_obj->threads)
{
auto thr = gdbpy_ref<>::new_reference ((PyObject *) entry.second.get ());
gdbpy_ref<> thr = entry.second;
if (PyTuple_SetItem (tuple.get (), i++, thr.release ()) < 0)
return nullptr;
}

View file

@ -197,9 +197,12 @@ public:
}
/* Acquire a new reference and return a ref_ptr that owns it. */
static ref_ptr<T, Policy> new_reference (T *obj)
template <class TObj>
static ref_ptr<T, Policy> new_reference (TObj *obj)
{
Policy::incref (obj);
if constexpr (std::is_base_of<T, TObj>::value)
return ref_ptr<T, Policy> (static_cast<T *> (obj));
return ref_ptr<T, Policy> (obj);
}