diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index fc16b9176fd1c0..957cede193853b 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -528,7 +528,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; } - dict = (StgDictObject *)_PyObject_CallNoArgs((PyObject *)&PyCStgDict_Type); + ctypes_state *st = GLOBAL_STATE(); + dict = (StgDictObject *) + _PyObject_CallNoArgs((PyObject *)st->PyCStgDict_Type); if (!dict) { Py_DECREF(result); return NULL; @@ -1087,8 +1089,9 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict items size, align, length contain info about pointers itself, stgdict->proto has info about the pointed to type! */ + ctypes_state *st = GLOBAL_STATE(); stgdict = (StgDictObject *)_PyObject_CallNoArgs( - (PyObject *)&PyCStgDict_Type); + (PyObject *)st->PyCStgDict_Type); if (!stgdict) return NULL; stgdict->size = sizeof(void *); @@ -1529,8 +1532,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } + ctypes_state *st = GLOBAL_STATE(); stgdict = (StgDictObject *)_PyObject_CallNoArgs( - (PyObject *)&PyCStgDict_Type); + (PyObject *)st->PyCStgDict_Type); if (!stgdict) goto error; @@ -1975,8 +1979,9 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject if (result == NULL) return NULL; + ctypes_state *st = GLOBAL_STATE(); stgdict = (StgDictObject *)_PyObject_CallNoArgs( - (PyObject *)&PyCStgDict_Type); + (PyObject *)st->PyCStgDict_Type); if (!stgdict) { Py_DECREF(result); return NULL; @@ -2086,8 +2091,9 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } + ctypes_state *st = GLOBAL_STATE(); stgdict = (StgDictObject *)_PyObject_CallNoArgs( - (PyObject *)&PyCStgDict_Type); + (PyObject *)st->PyCStgDict_Type); if (!stgdict) goto error; @@ -2532,8 +2538,9 @@ PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyTypeObject *result; StgDictObject *stgdict; + ctypes_state *st = GLOBAL_STATE(); stgdict = (StgDictObject *)_PyObject_CallNoArgs( - (PyObject *)&PyCStgDict_Type); + (PyObject *)st->PyCStgDict_Type); if (!stgdict) return NULL; @@ -5684,7 +5691,7 @@ _ctypes_add_types(PyObject *mod) CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec, NULL); TYPE_READY(&PyCData_Type); /* StgDict is derived from PyDict_Type */ - TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type); + CREATE_TYPE(mod, st->PyCStgDict_Type, &cstgdict_spec, &PyDict_Type); /************************************************* * diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 8891a0a741de7b..f420bbcdfdb15d 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -36,6 +36,7 @@ typedef struct { PyTypeObject *DictRemover_Type; PyTypeObject *PyCArg_Type; PyTypeObject *PyCField_Type; + PyTypeObject *PyCStgDict_Type; PyTypeObject *PyCThunk_Type; #ifdef MS_WIN32 PyTypeObject *PyComError_Type; @@ -49,6 +50,7 @@ extern ctypes_state global_state; extern PyType_Spec carg_spec; extern PyType_Spec cfield_spec; +extern PyType_Spec cstgdict_spec; extern PyType_Spec cthunk_spec; typedef struct tagPyCArgObject PyCArgObject; @@ -140,9 +142,8 @@ typedef struct { PyObject *paramflags; } PyCFuncPtrObject; -extern PyTypeObject PyCStgDict_Type; -#define PyCStgDict_CheckExact(v) Py_IS_TYPE(v, &PyCStgDict_Type) -#define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) +#define PyCStgDict_CheckExact(st, v) Py_IS_TYPE((v), (st)->PyCStgDict_Type) +#define PyCStgDict_Check(st, v) PyObject_TypeCheck((v), (st)->PyCStgDict_Type) extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index fb3e20e8db3e27..64f2f4f106a544 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -37,6 +37,18 @@ PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) return 0; } +static int +PyCStgDict_traverse(StgDictObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->proto); + Py_VISIT(self->argtypes); + Py_VISIT(self->converters); + Py_VISIT(self->restype); + Py_VISIT(self->checker); + return PyDict_Type.tp_traverse((PyObject *)self, visit, arg); +} + static int PyCStgDict_clear(StgDictObject *self) { @@ -45,17 +57,20 @@ PyCStgDict_clear(StgDictObject *self) Py_CLEAR(self->converters); Py_CLEAR(self->restype); Py_CLEAR(self->checker); - return 0; + return PyDict_Type.tp_clear((PyObject *)self); } static void PyCStgDict_dealloc(StgDictObject *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); PyCStgDict_clear(self); PyMem_Free(self->format); PyMem_Free(self->shape); PyMem_Free(self->ffi_type_pointer.elements); PyDict_Type.tp_dealloc((PyObject *)self); + Py_DECREF(tp); } static PyObject * @@ -136,46 +151,21 @@ static struct PyMethodDef PyCStgDict_methods[] = { {NULL, NULL} /* sentinel */ }; -PyTypeObject PyCStgDict_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "StgDict", - sizeof(StgDictObject), - 0, - (destructor)PyCStgDict_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PyCStgDict_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)PyCStgDict_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot cstgdict_slots[] = { + {Py_tp_dealloc, PyCStgDict_dealloc}, + {Py_tp_traverse, PyCStgDict_traverse}, + {Py_tp_clear, PyCStgDict_clear}, + {Py_tp_methods, PyCStgDict_methods}, + {Py_tp_init, PyCStgDict_init}, + {0, NULL}, +}; + +PyType_Spec cstgdict_spec = { + .name = "_ctypes.StgDict", + .basicsize = sizeof(StgDictObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = cstgdict_slots, }; /* May return NULL, but does not set an exception! */ @@ -187,7 +177,8 @@ PyType_stgdict(PyObject *obj) if (!PyType_Check(obj)) return NULL; type = (PyTypeObject *)obj; - if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) + ctypes_state *st = GLOBAL_STATE(); + if (!type->tp_dict || !PyCStgDict_CheckExact(st, type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } @@ -201,7 +192,8 @@ StgDictObject * PyObject_stgdict(PyObject *self) { PyTypeObject *type = Py_TYPE(self); - if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) + ctypes_state *st = GLOBAL_STATE(); + if (!type->tp_dict || !PyCStgDict_CheckExact(st, type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index e3a1b5d532bda2..526f52b0854655 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -369,14 +369,12 @@ Modules/_ctypes/ctypes.h - PyCFuncPtr_Type - Modules/_ctypes/ctypes.h - PyCPointerType_Type - Modules/_ctypes/ctypes.h - PyCPointer_Type - Modules/_ctypes/ctypes.h - PyCSimpleType_Type - -Modules/_ctypes/ctypes.h - PyCStgDict_Type - Modules/_ctypes/ctypes.h - PyCStructType_Type - Modules/_ctypes/ctypes.h - PyExc_ArgError - Modules/_ctypes/ctypes.h - _ctypes_conversion_encoding - Modules/_ctypes/ctypes.h - _ctypes_conversion_errors - Modules/_ctypes/ctypes.h - _ctypes_ptrtype_cache - Modules/_ctypes/ctypes.h - basespec_string - -Modules/_ctypes/stgdict.c - PyCStgDict_Type - Modules/_cursesmodule.c - PyCursesWindow_Type - Modules/_datetimemodule.c - PyDateTime_DateTimeType - Modules/_datetimemodule.c - PyDateTime_DateType -