]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdbpy_registry: cast C extension type object to PyObject * before Py_XINCREF
authorMatthieu Longo <matthieu.longo@arm.com>
Mon, 5 Jan 2026 11:14:28 +0000 (12:14 +0100)
committerMatthieu Longo <matthieu.longo@arm.com>
Thu, 29 Jan 2026 16:46:14 +0000 (16:46 +0000)
When enabling the Python limited API, pointers to Python C extension
objects can no longer be implicitly converted to 'PyObject *' by the
compiler.

The lookup() method of gbdpy_registry returns a new reference to the
type object of the looked-up entry. It does so by calling Py_XINCREF()
to increment the reference counter of the returned type object. The
template parameter obj_type corresponds to the type of C extension
object type. With the Python limited API enabled, obj_type can no longer
be implicitly converted to 'PyObject *' when passed to Py_XINCREF().

This patch fixes the resulting compilation issue by adding an explicit
static_cast to 'PyObject *' before passing the value to Py_XINCREF().
As a side effect, this cast enforces, at compile time, that the template
type 'Storage::obj_type' passed to gdbpy_registry is a subclass of
PyObject. To provide a clearer diagnostic when an incorrect type is used,
a static_assert is added to gdbpy_registry, avoiding obscure errors
originating from the static_cast. Finally, the relevant C extension types
passed to gdbpy_registry are updated to inherit publicly from PyObject.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
gdb/python/py-symbol.c
gdb/python/py-symtab.c
gdb/python/py-type.c
gdb/python/python-internal.h

index bd4023fa31acc595801a8f495ff41a436c2b859e..736774bd94f788fe7f1962fefcd17880a59a1dc6 100644 (file)
@@ -25,8 +25,8 @@
 #include "objfiles.h"
 #include "symfile.h"
 
-struct symbol_object {
-  PyObject_HEAD
+struct symbol_object : public PyObject
+{
   /* The GDB symbol structure this object is wrapping.  */
   struct symbol *symbol;
 };
index 9c093e70fc8dd75085d08e13a63b4b16bcd94417..2dca0083277b1c01057bbb0047748a6703cacec2 100644 (file)
@@ -24,8 +24,8 @@
 #include "objfiles.h"
 #include "block.h"
 
-struct symtab_object {
-  PyObject_HEAD
+struct symtab_object : public PyObject
+{
   /* The GDB Symbol table structure.  */
   struct symtab *symtab;
 };
@@ -47,8 +47,8 @@ static const gdbpy_registry<gdbpy_memoizing_registry_storage<symtab_object,
       }                                                         \
   } while (0)
 
-struct sal_object {
-  PyObject_HEAD
+struct sal_object : public PyObject
+{
   /* The GDB Symbol table and line structure.  */
   struct symtab_and_line *sal;
   /* A Symtab and line object is associated with an objfile, so keep
index 46004b93acd96244b4246087a6b06bdd095e3211..f39cb0240c8dcc59562b307bcb5554294bda0a91 100644 (file)
@@ -28,9 +28,8 @@
 #include "typeprint.h"
 #include "ada-lang.h"
 
-struct type_object
+struct type_object : public PyObject
 {
-  PyObject_HEAD
   struct type *type;
 };
 
index 65d2eee38ed26011412e8312d107cbf365bbb514..95619bf775e0e1cbedd70100754734696a7d3540 100644 (file)
@@ -1157,6 +1157,9 @@ public:
   using obj_type = typename Storage::obj_type;
   using val_type = typename Storage::val_type;
 
+  static_assert(std::is_base_of<PyObject, obj_type>::value,
+               "obj_type must be a subclass of PyObject");
+
   /* Register Python object OBJ as being "owned" by OWNER.  When OWNER is
      about to be freed, OBJ will be invalidated.  */
   template <typename O>
@@ -1180,7 +1183,7 @@ public:
   obj_type *lookup (O *owner, val_type *val) const
   {
     obj_type *obj = get_storage (owner)->lookup (val);
-    Py_XINCREF (obj);
+    Py_XINCREF (static_cast<PyObject *> (obj));
     return obj;
   }