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>
#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;
};
#include "objfiles.h"
#include "block.h"
-struct symtab_object {
- PyObject_HEAD
+struct symtab_object : public PyObject
+{
/* The GDB Symbol table structure. */
struct symtab *symtab;
};
} \
} 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
#include "typeprint.h"
#include "ada-lang.h"
-struct type_object
+struct type_object : public PyObject
{
- PyObject_HEAD
struct type *type;
};
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>
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;
}