gh-111178: fix UBSan failures in Modules/_operator.c (GH-129785)

Fix UBSan failures for `itemgetterobject`, `attrgetterobject`, `methodcallerobject`

Suppress unused return values
This commit is contained in:
Bénédikt Tran 2025-02-20 14:21:55 +01:00 committed by GitHub
parent e24a1ac17c
commit 4466e91360
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -999,13 +999,13 @@ static struct PyMethodDef operator_methods[] = {
static PyObject *
text_signature(PyObject *self, void *Py_UNUSED(ignored))
text_signature(PyObject *Py_UNUSED(self), void *Py_UNUSED(closure))
{
return PyUnicode_FromString("(obj, /)");
}
static PyGetSetDef common_getset[] = {
{"__text_signature__", text_signature, (setter)NULL},
{"__text_signature__", text_signature, NULL},
{NULL}
};
@ -1019,6 +1019,8 @@ typedef struct {
vectorcallfunc vectorcall;
} itemgetterobject;
#define itemgetterobject_CAST(op) ((itemgetterobject *)(op))
// Forward declarations
static PyObject *
itemgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
@ -1069,49 +1071,52 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
}
ig->vectorcall = (vectorcallfunc)itemgetter_vectorcall;
ig->vectorcall = itemgetter_vectorcall;
PyObject_GC_Track(ig);
return (PyObject *)ig;
}
static int
itemgetter_clear(itemgetterobject *ig)
itemgetter_clear(PyObject *op)
{
itemgetterobject *ig = itemgetterobject_CAST(op);
Py_CLEAR(ig->item);
return 0;
}
static void
itemgetter_dealloc(itemgetterobject *ig)
itemgetter_dealloc(PyObject *op)
{
PyTypeObject *tp = Py_TYPE(ig);
PyObject_GC_UnTrack(ig);
(void)itemgetter_clear(ig);
tp->tp_free(ig);
PyTypeObject *tp = Py_TYPE(op);
PyObject_GC_UnTrack(op);
(void)itemgetter_clear(op);
tp->tp_free(op);
Py_DECREF(tp);
}
static int
itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
itemgetter_traverse(PyObject *op, visitproc visit, void *arg)
{
itemgetterobject *ig = itemgetterobject_CAST(op);
Py_VISIT(Py_TYPE(ig));
Py_VISIT(ig->item);
return 0;
}
static PyObject *
itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
itemgetter_call(PyObject *op, PyObject *args, PyObject *kw)
{
assert(PyTuple_CheckExact(args));
if (!_PyArg_NoKeywords("itemgetter", kw))
return NULL;
if (!_PyArg_CheckPositional("itemgetter", PyTuple_GET_SIZE(args), 1, 1))
return NULL;
itemgetterobject *ig = itemgetterobject_CAST(op);
return itemgetter_call_impl(ig, PyTuple_GET_ITEM(args, 0));
}
static PyObject *
itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
itemgetter_vectorcall(PyObject *op, PyObject *const *args,
size_t nargsf, PyObject *kwnames)
{
if (!_PyArg_NoKwnames("itemgetter", kwnames)) {
@ -1121,7 +1126,8 @@ itemgetter_vectorcall(PyObject *ig, PyObject *const *args,
if (!_PyArg_CheckPositional("itemgetter", nargs, 1, 1)) {
return NULL;
}
return itemgetter_call_impl((itemgetterobject *)ig, args[0]);
itemgetterobject *ig = itemgetterobject_CAST(op);
return itemgetter_call_impl(ig, args[0]);
}
static PyObject *
@ -1161,12 +1167,13 @@ itemgetter_call_impl(itemgetterobject *ig, PyObject *obj)
}
static PyObject *
itemgetter_repr(itemgetterobject *ig)
itemgetter_repr(PyObject *op)
{
PyObject *repr;
const char *reprfmt;
itemgetterobject *ig = itemgetterobject_CAST(op);
int status = Py_ReprEnter((PyObject *)ig);
int status = Py_ReprEnter(op);
if (status != 0) {
if (status < 0)
return NULL;
@ -1175,13 +1182,14 @@ itemgetter_repr(itemgetterobject *ig)
reprfmt = ig->nitems == 1 ? "%s(%R)" : "%s%R";
repr = PyUnicode_FromFormat(reprfmt, Py_TYPE(ig)->tp_name, ig->item);
Py_ReprLeave((PyObject *)ig);
Py_ReprLeave(op);
return repr;
}
static PyObject *
itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
itemgetter_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
{
itemgetterobject *ig = itemgetterobject_CAST(op);
if (ig->nitems == 1)
return Py_BuildValue("O(O)", Py_TYPE(ig), ig->item);
return PyTuple_Pack(2, Py_TYPE(ig), ig->item);
@ -1190,7 +1198,7 @@ itemgetter_reduce(itemgetterobject *ig, PyObject *Py_UNUSED(ignored))
PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
static PyMethodDef itemgetter_methods[] = {
{"__reduce__", (PyCFunction)itemgetter_reduce, METH_NOARGS,
{"__reduce__", itemgetter_reduce, METH_NOARGS,
reduce_doc},
{NULL}
};
@ -1239,6 +1247,8 @@ typedef struct {
vectorcallfunc vectorcall;
} attrgetterobject;
#define attrgetterobject_CAST(op) ((attrgetterobject *)(op))
// Forward declarations
static PyObject *
attrgetter_vectorcall(PyObject *, PyObject *const *, size_t, PyObject *);
@ -1348,32 +1358,34 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
ag->attr = attr;
ag->nattrs = nattrs;
ag->vectorcall = (vectorcallfunc)attrgetter_vectorcall;
ag->vectorcall = attrgetter_vectorcall;
PyObject_GC_Track(ag);
return (PyObject *)ag;
}
static int
attrgetter_clear(attrgetterobject *ag)
attrgetter_clear(PyObject *op)
{
attrgetterobject *ag = attrgetterobject_CAST(op);
Py_CLEAR(ag->attr);
return 0;
}
static void
attrgetter_dealloc(attrgetterobject *ag)
attrgetter_dealloc(PyObject *op)
{
PyTypeObject *tp = Py_TYPE(ag);
PyObject_GC_UnTrack(ag);
(void)attrgetter_clear(ag);
tp->tp_free(ag);
PyTypeObject *tp = Py_TYPE(op);
PyObject_GC_UnTrack(op);
(void)attrgetter_clear(op);
tp->tp_free(op);
Py_DECREF(tp);
}
static int
attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
attrgetter_traverse(PyObject *op, visitproc visit, void *arg)
{
attrgetterobject *ag = attrgetterobject_CAST(op);
Py_VISIT(ag->attr);
Py_VISIT(Py_TYPE(ag));
return 0;
@ -1413,17 +1425,19 @@ dotted_getattr(PyObject *obj, PyObject *attr)
}
static PyObject *
attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
attrgetter_call(PyObject *op, PyObject *args, PyObject *kw)
{
if (!_PyArg_NoKeywords("attrgetter", kw))
return NULL;
if (!_PyArg_CheckPositional("attrgetter", PyTuple_GET_SIZE(args), 1, 1))
return NULL;
attrgetterobject *ag = attrgetterobject_CAST(op);
return attrgetter_call_impl(ag, PyTuple_GET_ITEM(args, 0));
}
static PyObject *
attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObject *kwnames)
attrgetter_vectorcall(PyObject *op, PyObject *const *args,
size_t nargsf, PyObject *kwnames)
{
if (!_PyArg_NoKwnames("attrgetter", kwnames)) {
return NULL;
@ -1432,7 +1446,8 @@ attrgetter_vectorcall(PyObject *ag, PyObject *const *args, size_t nargsf, PyObje
if (!_PyArg_CheckPositional("attrgetter", nargs, 1, 1)) {
return NULL;
}
return attrgetter_call_impl((attrgetterobject *)ag, args[0]);
attrgetterobject *ag = attrgetterobject_CAST(op);
return attrgetter_call_impl(ag, args[0]);
}
static PyObject *
@ -1505,10 +1520,11 @@ attrgetter_args(attrgetterobject *ag)
}
static PyObject *
attrgetter_repr(attrgetterobject *ag)
attrgetter_repr(PyObject *op)
{
PyObject *repr = NULL;
int status = Py_ReprEnter((PyObject *)ag);
attrgetterobject *ag = attrgetterobject_CAST(op);
int status = Py_ReprEnter(op);
if (status != 0) {
if (status < 0)
return NULL;
@ -1532,22 +1548,22 @@ attrgetter_repr(attrgetterobject *ag)
Py_DECREF(attrstrings);
}
}
Py_ReprLeave((PyObject *)ag);
Py_ReprLeave(op);
return repr;
}
static PyObject *
attrgetter_reduce(attrgetterobject *ag, PyObject *Py_UNUSED(ignored))
attrgetter_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
{
attrgetterobject *ag = attrgetterobject_CAST(op);
PyObject *attrstrings = attrgetter_args(ag);
if (attrstrings == NULL)
return NULL;
return Py_BuildValue("ON", Py_TYPE(ag), attrstrings);
}
static PyMethodDef attrgetter_methods[] = {
{"__reduce__", (PyCFunction)attrgetter_reduce, METH_NOARGS,
{"__reduce__", attrgetter_reduce, METH_NOARGS,
reduce_doc},
{NULL}
};
@ -1602,13 +1618,15 @@ typedef struct {
vectorcallfunc vectorcall;
} methodcallerobject;
#define methodcallerobject_CAST(op) ((methodcallerobject *)(op))
#define _METHODCALLER_MAX_ARGS 8
static PyObject *
methodcaller_vectorcall(methodcallerobject *mc, PyObject *const *args,
size_t nargsf, PyObject* kwnames)
methodcaller_vectorcall(PyObject *op, PyObject *const *args,
size_t nargsf, PyObject* kwnames)
{
methodcallerobject *mc = methodcallerobject_CAST(op);
if (!_PyArg_CheckPositional("methodcaller", PyVectorcall_NARGS(nargsf), 1, 1)
|| !_PyArg_NoKwnames("methodcaller", kwnames)) {
return NULL;
@ -1661,7 +1679,7 @@ _methodcaller_initialize_vectorcall(methodcallerobject* mc)
mc->vectorcall_kwnames = NULL;
}
mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
mc->vectorcall = methodcaller_vectorcall;
return 0;
}
@ -1721,8 +1739,9 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
static void
methodcaller_clear(methodcallerobject *mc)
methodcaller_clear(PyObject *op)
{
methodcallerobject *mc = methodcallerobject_CAST(op);
Py_CLEAR(mc->name);
Py_CLEAR(mc->args);
Py_CLEAR(mc->kwds);
@ -1731,18 +1750,19 @@ methodcaller_clear(methodcallerobject *mc)
}
static void
methodcaller_dealloc(methodcallerobject *mc)
methodcaller_dealloc(PyObject *op)
{
PyTypeObject *tp = Py_TYPE(mc);
PyObject_GC_UnTrack(mc);
methodcaller_clear(mc);
tp->tp_free(mc);
PyTypeObject *tp = Py_TYPE(op);
PyObject_GC_UnTrack(op);
(void)methodcaller_clear(op);
tp->tp_free(op);
Py_DECREF(tp);
}
static int
methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
methodcaller_traverse(PyObject *op, visitproc visit, void *arg)
{
methodcallerobject *mc = methodcallerobject_CAST(op);
Py_VISIT(mc->name);
Py_VISIT(mc->args);
Py_VISIT(mc->kwds);
@ -1753,9 +1773,10 @@ methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
}
static PyObject *
methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
methodcaller_call(PyObject *op, PyObject *args, PyObject *kw)
{
PyObject *method, *obj, *result;
methodcallerobject *mc = methodcallerobject_CAST(op);
if (!_PyArg_NoKeywords("methodcaller", kw))
return NULL;
@ -1772,11 +1793,12 @@ methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw)
}
static PyObject *
methodcaller_repr(methodcallerobject *mc)
methodcaller_repr(PyObject *op)
{
methodcallerobject *mc = methodcallerobject_CAST(op);
PyObject *argreprs, *repr = NULL, *sep, *joinedargreprs;
Py_ssize_t numtotalargs, numposargs, numkwdargs, i;
int status = Py_ReprEnter((PyObject *)mc);
int status = Py_ReprEnter(op);
if (status != 0) {
if (status < 0)
return NULL;
@ -1789,13 +1811,13 @@ methodcaller_repr(methodcallerobject *mc)
if (numtotalargs == 0) {
repr = PyUnicode_FromFormat("%s(%R)", Py_TYPE(mc)->tp_name, mc->name);
Py_ReprLeave((PyObject *)mc);
Py_ReprLeave(op);
return repr;
}
argreprs = PyTuple_New(numtotalargs);
if (argreprs == NULL) {
Py_ReprLeave((PyObject *)mc);
Py_ReprLeave(op);
return NULL;
}
@ -1843,13 +1865,14 @@ methodcaller_repr(methodcallerobject *mc)
done:
Py_DECREF(argreprs);
Py_ReprLeave((PyObject *)mc);
Py_ReprLeave(op);
return repr;
}
static PyObject *
methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
methodcaller_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
{
methodcallerobject *mc = methodcallerobject_CAST(op);
if (!mc->kwds || PyDict_GET_SIZE(mc->kwds) == 0) {
Py_ssize_t i;
Py_ssize_t callargcount = PyTuple_GET_SIZE(mc->args);
@ -1882,7 +1905,7 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored))
}
static PyMethodDef methodcaller_methods[] = {
{"__reduce__", (PyCFunction)methodcaller_reduce, METH_NOARGS,
{"__reduce__", methodcaller_reduce, METH_NOARGS,
reduce_doc},
{NULL}
};
@ -1985,7 +2008,7 @@ operator_clear(PyObject *module)
static void
operator_free(void *module)
{
operator_clear((PyObject *)module);
(void)operator_clear((PyObject *)module);
}
static struct PyModuleDef operatormodule = {