]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111178: fix UBSan failures in `Modules/_ctypes` (#129071)
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>
Tue, 21 Jan 2025 10:50:13 +0000 (11:50 +0100)
committerGitHub <noreply@github.com>
Tue, 21 Jan 2025 10:50:13 +0000 (11:50 +0100)
This fixes UBSan failures for the following objects:

- `DictRemoverObject` and `StructParamObject`,
- `CDataObject` and `CFieldObject`, and
- `PyCFuncPtrObject` and `PyCArgObject`.

On the default build, we convert the `LOCK_PTR` and `UNLOCK_PTR` macros to
functions with an unused parameter to ease "unused variable" compiler warnings
suppression. Finally, we also remove some redundant casts to `PyObject *`.

Modules/_ctypes/_ctypes.c
Modules/_ctypes/callproc.c
Modules/_ctypes/cfield.c
Modules/_ctypes/ctypes.h

index 5d37610cc1c97034cfd652b0a3b34f74052d18a4..d86adec0aeca585926a896fe322bf1b37c00e496 100644 (file)
@@ -146,9 +146,12 @@ typedef struct {
     PyObject *dict;
 } DictRemoverObject;
 
+#define _DictRemoverObject_CAST(op)     ((DictRemoverObject *)(op))
+
 static int
-_DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
+_DictRemover_traverse(PyObject *myself, visitproc visit, void *arg)
 {
+    DictRemoverObject *self = _DictRemoverObject_CAST(myself);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->key);
     Py_VISIT(self->dict);
@@ -156,8 +159,9 @@ _DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
 }
 
 static int
-_DictRemover_clear(DictRemoverObject *self)
+_DictRemover_clear(PyObject *myself)
 {
+    DictRemoverObject *self = _DictRemoverObject_CAST(myself);
     Py_CLEAR(self->key);
     Py_CLEAR(self->dict);
     return 0;
@@ -167,9 +171,8 @@ static void
 _DictRemover_dealloc(PyObject *myself)
 {
     PyTypeObject *tp = Py_TYPE(myself);
-    DictRemoverObject *self = (DictRemoverObject *)myself;
     PyObject_GC_UnTrack(myself);
-    (void)_DictRemover_clear(self);
+    (void)_DictRemover_clear(myself);
     tp->tp_free(myself);
     Py_DECREF(tp);
 }
@@ -177,7 +180,7 @@ _DictRemover_dealloc(PyObject *myself)
 static PyObject *
 _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
 {
-    DictRemoverObject *self = (DictRemoverObject *)myself;
+    DictRemoverObject *self = _DictRemoverObject_CAST(myself);
     if (self->key && self->dict) {
         if (-1 == PyDict_DelItem(self->dict, self->key)) {
             PyErr_FormatUnraisable("Exception ignored on calling _ctypes.DictRemover");
@@ -402,16 +405,19 @@ typedef struct {
     PyObject *keep;  // If set, a reference to the original CDataObject.
 } StructParamObject;
 
+#define _StructParamObject_CAST(op) ((StructParamObject *)(op))
+
 static int
-StructParam_traverse(StructParamObject *self, visitproc visit, void *arg)
+StructParam_traverse(PyObject *self, visitproc visit, void *arg)
 {
     Py_VISIT(Py_TYPE(self));
     return 0;
 }
 
 static int
-StructParam_clear(StructParamObject *self)
+StructParam_clear(PyObject *myself)
 {
+    StructParamObject *self = _StructParamObject_CAST(myself);
     Py_CLEAR(self->keep);
     return 0;
 }
@@ -419,10 +425,10 @@ StructParam_clear(StructParamObject *self)
 static void
 StructParam_dealloc(PyObject *myself)
 {
-    StructParamObject *self = (StructParamObject *)myself;
+    StructParamObject *self = _StructParamObject_CAST(myself);
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(myself);
-    (void)StructParam_clear(self);
+    (void)StructParam_clear(myself);
     PyMem_Free(self->ptr);
     tp->tp_free(myself);
     Py_DECREF(tp);
@@ -675,7 +681,7 @@ StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruc
 
     info->paramfunc = StructUnionType_paramfunc;
 
-    if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_fields_), &fields) < 0) {
+    if (PyDict_GetItemRef(attrdict, &_Py_ID(_fields_), &fields) < 0) {
         Py_DECREF(attrdict);
         return -1;
     }
@@ -1411,11 +1417,12 @@ static PyType_Spec pycpointer_type_spec = {
 */
 
 static int
-CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+CharArray_set_raw(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
 {
     char *ptr;
     Py_ssize_t size;
     Py_buffer view;
+    CDataObject *self = _CDataObject_CAST(op);
 
     if (value == NULL) {
         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
@@ -1441,9 +1448,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
 }
 
 static PyObject *
-CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
+CharArray_get_raw(PyObject *op, void *Py_UNUSED(ignored))
 {
     PyObject *res;
+    CDataObject *self = _CDataObject_CAST(op);
     LOCK_PTR(self);
     res = PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
     UNLOCK_PTR(self);
@@ -1451,10 +1459,11 @@ CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
 }
 
 static PyObject *
-CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+CharArray_get_value(PyObject *op, void *Py_UNUSED(ignored))
 {
     Py_ssize_t i;
     PyObject *res;
+    CDataObject *self = _CDataObject_CAST(op);
     LOCK_PTR(self);
     char *ptr = self->b_ptr;
     for (i = 0; i < self->b_size; ++i)
@@ -1466,10 +1475,11 @@ CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
 }
 
 static int
-CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+CharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
 {
     const char *ptr;
     Py_ssize_t size;
+    CDataObject *self = _CDataObject_CAST(op);
 
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
@@ -1504,18 +1514,17 @@ CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)
 }
 
 static PyGetSetDef CharArray_getsets[] = {
-    { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
-      "value", NULL },
-    { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
-      "string value"},
+    { "raw", CharArray_get_raw, CharArray_set_raw, "value", NULL },
+    { "value", CharArray_get_value, CharArray_set_value, "string value" },
     { NULL, NULL }
 };
 
 static PyObject *
-WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+WCharArray_get_value(PyObject *op, void *Py_UNUSED(ignored))
 {
     Py_ssize_t i;
     PyObject *res;
+    CDataObject *self = _CDataObject_CAST(op);
     wchar_t *ptr = (wchar_t *)self->b_ptr;
     LOCK_PTR(self);
     for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
@@ -1527,8 +1536,10 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
 }
 
 static int
-WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+WCharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
 {
+    CDataObject *self = _CDataObject_CAST(op);
+
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
                         "can't delete attribute");
@@ -1561,8 +1572,7 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored
 }
 
 static PyGetSetDef WCharArray_getsets[] = {
-    { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
-      "string value"},
+    { "value", WCharArray_get_value, WCharArray_set_value, "string value" },
     { NULL, NULL }
 };
 
@@ -2627,7 +2637,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
     stginfo->getfunc = NULL;
     stginfo->ffi_type_pointer = ffi_type_pointer;
 
-    if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_flags_), &ob) < 0) {
+    if (PyDict_GetItemRef(attrdict, &_Py_ID(_flags_), &ob) < 0) {
         return -1;
     }
     if (!ob || !PyLong_Check(ob)) {
@@ -2640,7 +2650,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
     Py_DECREF(ob);
 
     /* _argtypes_ is optional... */
-    if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_argtypes_), &ob) < 0) {
+    if (PyDict_GetItemRef(attrdict, &_Py_ID(_argtypes_), &ob) < 0) {
         return -1;
     }
     if (ob) {
@@ -2653,7 +2663,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
         stginfo->converters = converters;
     }
 
-    if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_restype_), &ob) < 0) {
+    if (PyDict_GetItemRef(attrdict, &_Py_ID(_restype_), &ob) < 0) {
         return -1;
     }
     if (ob) {
@@ -2675,7 +2685,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
         }
     }
 /* XXX later, maybe.
-    if (PyDict_GetItemRef((PyObject *)attrdict, &_Py _ID(_errcheck_), &ob) < 0) {
+    if (PyDict_GetItemRef(attrdict, &_Py _ID(_errcheck_), &ob) < 0) {
         return -1;
     }
     if (ob) {
@@ -2877,8 +2887,9 @@ class _ctypes.PyCData "PyObject *" "clinic_state()->PyCData_Type"
 
 
 static int
-PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
+PyCData_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    CDataObject *self = _CDataObject_CAST(op);
     Py_VISIT(self->b_objects);
     Py_VISIT((PyObject *)self->b_base);
     PyTypeObject *type = Py_TYPE(self);
@@ -2887,8 +2898,9 @@ PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
 }
 
 static int
-PyCData_clear(CDataObject *self)
+PyCData_clear(PyObject *op)
 {
+    CDataObject *self = _CDataObject_CAST(op);
     Py_CLEAR(self->b_objects);
     if ((self->b_needsfree)
         && _CDataObject_HasExternalBuffer(self))
@@ -2903,7 +2915,7 @@ PyCData_dealloc(PyObject *self)
 {
     PyTypeObject *type = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
-    PyCData_clear((CDataObject *)self);
+    (void)PyCData_clear(self);
     type->tp_free(self);
     Py_DECREF(type);
 }
@@ -2946,7 +2958,7 @@ PyCData_item_type(ctypes_state *st, PyObject *type)
 static int
 PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
     StgInfo *info;
@@ -3005,7 +3017,7 @@ static PyObject *
 PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
 /*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
 
     ctypes_state *st = get_module_state_by_class(cls);
     StgInfo *info;
@@ -3038,7 +3050,7 @@ PyCData_setstate(PyObject *myself, PyObject *args)
     Py_ssize_t len;
     int res;
     PyObject *dict, *mydict;
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     if (!PyArg_ParseTuple(args, "O!s#",
                           &PyDict_Type, &dict, &data, &len))
     {
@@ -3238,10 +3250,7 @@ PyObject *
 PyCData_get(ctypes_state *st, PyObject *type, GETFUNC getfunc, PyObject *src,
           Py_ssize_t index, Py_ssize_t size, char *adr)
 {
-#ifdef Py_GIL_DISABLED
-    // This isn't used if the GIL is enabled, so it causes a compiler warning.
-    CDataObject *cdata = (CDataObject *)src;
-#endif
+    CDataObject *cdata = _CDataObject_CAST(src);
     if (getfunc) {
         PyObject *res;
         LOCK_PTR(cdata);
@@ -4394,7 +4403,7 @@ _build_result(PyObject *result, PyObject *callargs,
 }
 
 static PyObject *
-PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
+PyCFuncPtr_call(PyObject *op, PyObject *inargs, PyObject *kwds)
 {
     PyObject *restype;
     PyObject *converters;
@@ -4407,6 +4416,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
     IUnknown *piunk = NULL;
 #endif
     void *pProc = NULL;
+    PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
 
     int inoutmask;
     int outmask;
@@ -4414,7 +4424,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *info;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+    if (PyStgInfo_FromObject(st, op, &info) < 0) {
         return NULL;
     }
     assert(info); /* Cannot be NULL for PyCFuncPtrObject instances */
@@ -4532,8 +4542,9 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
 }
 
 static int
-PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
+PyCFuncPtr_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
     Py_VISIT(self->callable);
     Py_VISIT(self->restype);
     Py_VISIT(self->checker);
@@ -4542,12 +4553,13 @@ PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
     Py_VISIT(self->converters);
     Py_VISIT(self->paramflags);
     Py_VISIT(self->thunk);
-    return PyCData_traverse((CDataObject *)self, visit, arg);
+    return PyCData_traverse(op, visit, arg);
 }
 
 static int
-PyCFuncPtr_clear(PyCFuncPtrObject *self)
+PyCFuncPtr_clear(PyObject *op)
 {
+    PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
     Py_CLEAR(self->callable);
     Py_CLEAR(self->restype);
     Py_CLEAR(self->checker);
@@ -4556,22 +4568,23 @@ PyCFuncPtr_clear(PyCFuncPtrObject *self)
     Py_CLEAR(self->converters);
     Py_CLEAR(self->paramflags);
     Py_CLEAR(self->thunk);
-    return PyCData_clear((CDataObject *)self);
+    return PyCData_clear(op);
 }
 
 static void
-PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
+PyCFuncPtr_dealloc(PyObject *self)
 {
     PyObject_GC_UnTrack(self);
-    PyCFuncPtr_clear(self);
+    (void)PyCFuncPtr_clear(self);
     PyTypeObject *type = Py_TYPE(self);
-    type->tp_free((PyObject *)self);
+    type->tp_free(self);
     Py_DECREF(type);
 }
 
 static PyObject *
-PyCFuncPtr_repr(PyCFuncPtrObject *self)
+PyCFuncPtr_repr(PyObject *op)
 {
+    PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
 #ifdef MS_WIN32
     if (self->index)
         return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
@@ -4585,8 +4598,9 @@ PyCFuncPtr_repr(PyCFuncPtrObject *self)
 }
 
 static int
-PyCFuncPtr_bool(PyCFuncPtrObject *self)
+PyCFuncPtr_bool(PyObject *op)
 {
+    PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
     return ((*(void **)self->b_ptr != NULL)
 #ifdef MS_WIN32
         || (self->index != 0)
@@ -4774,7 +4788,7 @@ static PyType_Spec pycunion_spec = {
   PyCArray_Type
 */
 static int
-Array_init(CDataObject *self, PyObject *args, PyObject *kw)
+Array_init(PyObject *self, PyObject *args, PyObject *kw)
 {
     Py_ssize_t i;
     Py_ssize_t n;
@@ -4788,7 +4802,7 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw)
     for (i = 0; i < n; ++i) {
         PyObject *v;
         v = PyTuple_GET_ITEM(args, i);
-        if (-1 == PySequence_SetItem((PyObject *)self, i, v))
+        if (-1 == PySequence_SetItem(self, i, v))
             return -1;
     }
     return 0;
@@ -4797,7 +4811,7 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw)
 static PyObject *
 Array_item(PyObject *myself, Py_ssize_t index)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     Py_ssize_t offset, size;
 
     if (index < 0 || index >= self->b_length) {
@@ -4808,7 +4822,7 @@ Array_item(PyObject *myself, Py_ssize_t index)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
         return NULL;
     }
 
@@ -4818,14 +4832,14 @@ Array_item(PyObject *myself, Py_ssize_t index)
     size = stginfo->size / stginfo->length;
     offset = index * size;
 
-    return PyCData_get(st, stginfo->proto, stginfo->getfunc, (PyObject *)self,
-                     index, size, self->b_ptr + offset);
+    return PyCData_get(st, stginfo->proto, stginfo->getfunc, myself,
+                       index, size, self->b_ptr + offset);
 }
 
 static PyObject *
 Array_subscript(PyObject *myself, PyObject *item)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
 
     if (PyIndex_Check(item)) {
         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
@@ -4849,7 +4863,7 @@ Array_subscript(PyObject *myself, PyObject *item)
 
         ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
         StgInfo *stginfo;
-        if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+        if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
             return NULL;
         }
         assert(stginfo); /* Cannot be NULL for array object instances */
@@ -4950,7 +4964,7 @@ Array_subscript(PyObject *myself, PyObject *item)
 static int
 Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     Py_ssize_t size, offset;
     char *ptr;
 
@@ -4962,7 +4976,7 @@ Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
         return -1;
     }
     assert(stginfo); /* Cannot be NULL for array object instances */
@@ -4976,14 +4990,14 @@ Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
     offset = index * size;
     ptr = self->b_ptr + offset;
 
-    return PyCData_set(st, (PyObject *)self, stginfo->proto, stginfo->setfunc, value,
-                     index, size, ptr);
+    return PyCData_set(st, myself, stginfo->proto, stginfo->setfunc, value,
+                       index, size, ptr);
 }
 
 static int
 Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
 
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
@@ -5040,7 +5054,7 @@ Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
 static Py_ssize_t
 Array_length(PyObject *myself)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     return self->b_length;
 }
 
@@ -5157,9 +5171,10 @@ class _ctypes.Simple "PyObject *" "clinic_state()->Simple_Type"
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=016c476c7aa8b8a8]*/
 
 static int
-Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+Simple_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
 {
     PyObject *result;
+    CDataObject *self = _CDataObject_CAST(op);
 
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
@@ -5169,7 +5184,7 @@ Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *info;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+    if (PyStgInfo_FromObject(st, op, &info) < 0) {
         return -1;
     }
     assert(info); /* Cannot be NULL for CDataObject instances */
@@ -5186,7 +5201,7 @@ Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
 }
 
 static int
-Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
+Simple_init(PyObject *self, PyObject *args, PyObject *kw)
 {
     PyObject *value = NULL;
     if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
@@ -5197,11 +5212,12 @@ Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
 }
 
 static PyObject *
-Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+Simple_get_value(PyObject *op, void *Py_UNUSED(ignored))
 {
+    CDataObject *self = _CDataObject_CAST(op);
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *info;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+    if (PyStgInfo_FromObject(st, op, &info) < 0) {
         return NULL;
     }
     assert(info); /* Cannot be NULL for CDataObject instances */
@@ -5214,7 +5230,7 @@ Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
 }
 
 static PyGetSetDef Simple_getsets[] = {
-    { "value", (getter)Simple_get_value, (setter)Simple_set_value,
+    { "value", Simple_get_value, Simple_set_value,
       "current value", NULL },
     { NULL, NULL }
 };
@@ -5236,7 +5252,7 @@ Simple_from_outparm_impl(PyObject *self, PyTypeObject *cls)
         return Py_NewRef(self);
     }
     /* call stginfo->getfunc */
-    return Simple_get_value((CDataObject *)self, NULL);
+    return Simple_get_value(self, NULL);
 }
 
 static PyMethodDef Simple_methods[] = {
@@ -5244,9 +5260,11 @@ static PyMethodDef Simple_methods[] = {
     { NULL, NULL },
 };
 
-static int Simple_bool(CDataObject *self)
+static int
+Simple_bool(PyObject *op)
 {
     int cmp;
+    CDataObject *self = _CDataObject_CAST(op);
     LOCK_PTR(self);
     cmp = memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
     UNLOCK_PTR(self);
@@ -5255,7 +5273,7 @@ static int Simple_bool(CDataObject *self)
 
 /* "%s(%s)" % (self.__class__.__name__, self.value) */
 static PyObject *
-Simple_repr(CDataObject *self)
+Simple_repr(PyObject *self)
 {
     PyObject *val, *result;
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
@@ -5302,7 +5320,7 @@ static PyType_Spec pycsimple_spec = {
 static PyObject *
 Pointer_item(PyObject *myself, Py_ssize_t index)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     Py_ssize_t size;
     Py_ssize_t offset;
     PyObject *proto;
@@ -5316,7 +5334,7 @@ Pointer_item(PyObject *myself, Py_ssize_t index)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
         return NULL;
     }
     assert(stginfo); /* Cannot be NULL for pointer object instances */
@@ -5334,14 +5352,14 @@ Pointer_item(PyObject *myself, Py_ssize_t index)
     size = iteminfo->size;
     offset = index * iteminfo->size;
 
-    return PyCData_get(st, proto, stginfo->getfunc, (PyObject *)self,
+    return PyCData_get(st, proto, stginfo->getfunc, myself,
                        index, size, (char *)((char *)deref + offset));
 }
 
 static int
 Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     Py_ssize_t size;
     Py_ssize_t offset;
     PyObject *proto;
@@ -5361,7 +5379,7 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
         return -1;
     }
     assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5379,14 +5397,14 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
     size = iteminfo->size;
     offset = index * iteminfo->size;
 
-    return PyCData_set(st, (PyObject *)self, proto, stginfo->setfunc, value,
+    return PyCData_set(st, myself, proto, stginfo->setfunc, value,
                        index, size, ((char *)deref + offset));
 }
 
 static PyObject *
-Pointer_get_contents(CDataObject *self, void *closure)
+Pointer_get_contents(PyObject *self, void *closure)
 {
-    void *deref = locked_deref(self);
+    void *deref = locked_deref(_CDataObject_CAST(self));
     if (deref == NULL) {
         PyErr_SetString(PyExc_ValueError,
                         "NULL pointer access");
@@ -5395,21 +5413,20 @@ Pointer_get_contents(CDataObject *self, void *closure)
 
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, self, &stginfo) < 0) {
         return NULL;
     }
     assert(stginfo); /* Cannot be NULL for pointer instances */
 
-    return PyCData_FromBaseObj(st, stginfo->proto,
-                             (PyObject *)self, 0,
-                             deref);
+    return PyCData_FromBaseObj(st, stginfo->proto, self, 0, deref);
 }
 
 static int
-Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
+Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
 {
     CDataObject *dst;
     PyObject *keep;
+    CDataObject *self = _CDataObject_CAST(op);
 
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
@@ -5418,7 +5435,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
     }
     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
     StgInfo *stginfo;
-    if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+    if (PyStgInfo_FromObject(st, op, &stginfo) < 0) {
         return -1;
     }
     assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5457,17 +5474,15 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
 }
 
 static PyGetSetDef Pointer_getsets[] = {
-    { "contents", (getter)Pointer_get_contents,
-      (setter)Pointer_set_contents,
+    { "contents", Pointer_get_contents, Pointer_set_contents,
       "the object this pointer points to (read-write)", NULL },
     { NULL, NULL }
 };
 
 static int
-Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
+Pointer_init(PyObject *self, PyObject *args, PyObject *kw)
 {
     PyObject *value = NULL;
-
     if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
         return -1;
     if (value == NULL)
@@ -5494,7 +5509,7 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
 static PyObject *
 Pointer_subscript(PyObject *myself, PyObject *item)
 {
-    CDataObject *self = (CDataObject *)myself;
+    CDataObject *self = _CDataObject_CAST(myself);
     if (PyIndex_Check(item)) {
         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
         if (i == -1 && PyErr_Occurred())
@@ -5560,7 +5575,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
 
         ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
         StgInfo *stginfo;
-        if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+        if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
             return NULL;
         }
         assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5642,13 +5657,13 @@ Pointer_subscript(PyObject *myself, PyObject *item)
 }
 
 static int
-Pointer_bool(CDataObject *self)
+Pointer_bool(PyObject *self)
 {
-    return locked_deref(self) != NULL;
+    return locked_deref(_CDataObject_CAST(self)) != NULL;
 }
 
 static PyType_Slot pycpointer_slots[] = {
-    {Py_tp_doc, PyDoc_STR("XXX to be provided")},
+    {Py_tp_doc, (void *)PyDoc_STR("XXX to be provided")},
     {Py_tp_getset, Pointer_getsets},
     {Py_tp_init, Pointer_init},
     {Py_tp_new, Pointer_new},
index 92eedff5ec94f189027f097d68c95e8b8253c8b3..c6b6460126ca904697c8b12b6d30839e3a25a1de 100644 (file)
@@ -493,27 +493,29 @@ PyCArgObject_new(ctypes_state *st)
 }
 
 static int
-PyCArg_traverse(PyCArgObject *self, visitproc visit, void *arg)
+PyCArg_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    PyCArgObject *self = _PyCArgObject_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->obj);
     return 0;
 }
 
 static int
-PyCArg_clear(PyCArgObject *self)
+PyCArg_clear(PyObject *op)
 {
+    PyCArgObject *self = _PyCArgObject_CAST(op);
     Py_CLEAR(self->obj);
     return 0;
 }
 
 static void
-PyCArg_dealloc(PyCArgObject *self)
+PyCArg_dealloc(PyObject *self)
 {
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
     (void)PyCArg_clear(self);
-    tp->tp_free((PyObject *)self);
+    tp->tp_free(self);
     Py_DECREF(tp);
 }
 
@@ -524,8 +526,9 @@ is_literal_char(unsigned char c)
 }
 
 static PyObject *
-PyCArg_repr(PyCArgObject *self)
+PyCArg_repr(PyObject *op)
 {
+    PyCArgObject *self = _PyCArgObject_CAST(op);
     switch(self->tag) {
     case 'b':
     case 'B':
index e045d206f05580957874f78be7a4ca544c6e2805..9924d62c0881d1f0243363b8481f19391bed5d48 100644 (file)
@@ -194,17 +194,18 @@ error:
 
 
 static int
-PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
+PyCField_set(PyObject *op, PyObject *inst, PyObject *value)
 {
     CDataObject *dst;
     char *ptr;
+    CFieldObject *self = _CFieldObject_CAST(op);
     ctypes_state *st = get_module_state_by_class(Py_TYPE(self));
     if (!CDataObject_Check(st, inst)) {
         PyErr_SetString(PyExc_TypeError,
                         "not a ctype instance");
         return -1;
     }
-    dst = (CDataObject *)inst;
+    dst = _CDataObject_CAST(inst);
     ptr = dst->b_ptr + self->offset;
     if (value == NULL) {
         PyErr_SetString(PyExc_TypeError,
@@ -212,13 +213,14 @@ PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
         return -1;
     }
     return PyCData_set(st, inst, self->proto, self->setfunc, value,
-                     self->index, self->size, ptr);
+                       self->index, self->size, ptr);
 }
 
 static PyObject *
-PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
+PyCField_get(PyObject *op, PyObject *inst, PyTypeObject *type)
 {
     CDataObject *src;
+    CFieldObject *self = _CFieldObject_CAST(op);
     if (inst == NULL) {
         return Py_NewRef(self);
     }
@@ -228,21 +230,21 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
                         "not a ctype instance");
         return NULL;
     }
-    src = (CDataObject *)inst;
+    src = _CDataObject_CAST(inst);
     return PyCData_get(st, self->proto, self->getfunc, inst,
-                     self->index, self->size, src->b_ptr + self->offset);
+                       self->index, self->size, src->b_ptr + self->offset);
 }
 
 static PyObject *
 PyCField_get_offset(PyObject *self, void *data)
 {
-    return PyLong_FromSsize_t(((CFieldObject *)self)->offset);
+    return PyLong_FromSsize_t(_CFieldObject_CAST(self)->offset);
 }
 
 static PyObject *
 PyCField_get_size(PyObject *self, void *data)
 {
-    return PyLong_FromSsize_t(((CFieldObject *)self)->size);
+    return PyLong_FromSsize_t(_CFieldObject_CAST(self)->size);
 }
 
 static PyGetSetDef PyCField_getset[] = {
@@ -252,17 +254,20 @@ static PyGetSetDef PyCField_getset[] = {
 };
 
 static int
-PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
+PyCField_traverse(PyObject *op, visitproc visit, void *arg)
 {
+    CFieldObject *self = _CFieldObject_CAST(op);
     Py_VISIT(Py_TYPE(self));
     Py_VISIT(self->proto);
     return 0;
 }
 
 static int
-PyCField_clear(CFieldObject *self)
+PyCField_clear(PyObject *op)
 {
+    CFieldObject *self = _CFieldObject_CAST(op);
     Py_CLEAR(self->proto);
+    Py_CLEAR(self->name);
     return 0;
 }
 
@@ -271,17 +276,16 @@ PyCField_dealloc(PyObject *self)
 {
     PyTypeObject *tp = Py_TYPE(self);
     PyObject_GC_UnTrack(self);
-    CFieldObject *self_cf = (CFieldObject *)self;
-    (void)PyCField_clear(self_cf);
-    Py_CLEAR(self_cf->name);
+    (void)PyCField_clear(self);
     Py_TYPE(self)->tp_free(self);
     Py_DECREF(tp);
 }
 
 static PyObject *
-PyCField_repr(CFieldObject *self)
+PyCField_repr(PyObject *op)
 {
     PyObject *result;
+    CFieldObject *self = _CFieldObject_CAST(op);
     Py_ssize_t bits = NUM_BITS(self->size);
     Py_ssize_t size = LOW_BIT(self->size);
     const char *name;
index 9e8097feae2c1787000eda593e24524f8bea4cd2..1330754a7e0607e39f6db5699ea68fd764d5c762 100644 (file)
@@ -121,7 +121,10 @@ extern PyType_Spec cfield_spec;
 extern PyType_Spec cthunk_spec;
 
 typedef struct tagPyCArgObject PyCArgObject;
+#define _PyCArgObject_CAST(op)  ((PyCArgObject *)(op))
+
 typedef struct tagCDataObject CDataObject;
+#define _CDataObject_CAST(op)   ((CDataObject *)(op))
 
 // GETFUNC: convert the C value at *ptr* to Python object, return the object
 // SETFUNC: write content of the PyObject *value* to the location at *ptr*;
@@ -185,6 +188,8 @@ typedef struct {
     ffi_type *ffi_restype;
     ffi_type *atypes[1];
 } CThunkObject;
+
+#define _CThunkObject_CAST(op)          ((CThunkObject *)(op))
 #define CThunk_CheckExact(st, v)        Py_IS_TYPE(v, st->PyCThunk_Type)
 
 typedef struct {
@@ -218,6 +223,8 @@ typedef struct {
     PyObject *paramflags;
 } PyCFuncPtrObject;
 
+#define _PyCFuncPtrObject_CAST(op)  ((PyCFuncPtrObject *)(op))
+
 extern int PyCStructUnionType_update_stginfo(PyObject *fields, PyObject *type, int isStruct);
 extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
 extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
@@ -281,6 +288,8 @@ typedef struct CFieldObject {
     PyObject *name;                     /* exact PyUnicode */
 } CFieldObject;
 
+#define _CFieldObject_CAST(op)  ((CFieldObject *)(op))
+
 /****************************************************************
  StgInfo
 
@@ -417,6 +426,8 @@ struct tagPyCArgObject {
     Py_ssize_t size; /* for the 'V' tag */
 };
 
+#define _PyCArgObject_CAST(op)  ((PyCArgObject *)(op))
+
 #define PyCArg_CheckExact(st, v)        Py_IS_TYPE(v, st->PyCArg_Type)
 extern PyCArgObject *PyCArgObject_new(ctypes_state *st);
 
@@ -562,8 +573,12 @@ PyStgInfo_Init(ctypes_state *state, PyTypeObject *type)
 #  define LOCK_PTR(self) Py_BEGIN_CRITICAL_SECTION(self)
 #  define UNLOCK_PTR(self) Py_END_CRITICAL_SECTION()
 #else
-#  define LOCK_PTR(self)
-#  define UNLOCK_PTR(self)
+/*
+ * Dummy functions instead of macros so that 'self' can be
+ * unused in the caller without triggering a compiler warning.
+ */
+static inline void LOCK_PTR(CDataObject *Py_UNUSED(self)) {}
+static inline void UNLOCK_PTR(CDataObject *Py_UNUSED(self)) {}
 #endif
 
 static inline void