gh-111178: fix UBSan failures in Objects/floatobject.c (GH-129776)

fix UBSan failures for `PyFloatObject`
This commit is contained in:
Bénédikt Tran 2025-02-08 14:47:19 +01:00 committed by GitHub
parent 624b93ed67
commit 12e1d3011b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -369,8 +369,9 @@ _Py_convert_int_to_double(PyObject **v, double *dbl)
}
static PyObject *
float_repr(PyFloatObject *v)
float_repr(PyObject *op)
{
PyFloatObject *v = _PyFloat_CAST(op);
PyObject *result;
char *buf;
@ -579,9 +580,10 @@ float_richcompare(PyObject *v, PyObject *w, int op)
}
static Py_hash_t
float_hash(PyFloatObject *v)
float_hash(PyObject *op)
{
return _Py_HashDouble((PyObject *)v, v->ob_fval);
PyFloatObject *v = _PyFloat_CAST(op);
return _Py_HashDouble(op, v->ob_fval);
}
static PyObject *
@ -851,20 +853,23 @@ float_pow(PyObject *v, PyObject *w, PyObject *z)
#undef DOUBLE_IS_ODD_INTEGER
static PyObject *
float_neg(PyFloatObject *v)
float_neg(PyObject *op)
{
PyFloatObject *v = _PyFloat_CAST(op);
return PyFloat_FromDouble(-v->ob_fval);
}
static PyObject *
float_abs(PyFloatObject *v)
float_abs(PyObject *op)
{
PyFloatObject *v = _PyFloat_CAST(op);
return PyFloat_FromDouble(fabs(v->ob_fval));
}
static int
float_bool(PyFloatObject *v)
float_bool(PyObject *op)
{
PyFloatObject *v = _PyFloat_CAST(op);
return v->ob_fval != 0.0;
}
@ -1206,7 +1211,7 @@ float_hex_impl(PyObject *self)
CONVERT_TO_DOUBLE(self, x);
if (isnan(x) || isinf(x))
return float_repr((PyFloatObject *)self);
return float_repr(self);
if (x == 0.0) {
if (copysign(1.0, x) == -1.0)
@ -1651,7 +1656,7 @@ float_subtype_new(PyTypeObject *type, PyObject *x)
}
static PyObject *
float_vectorcall(PyObject *type, PyObject * const*args,
float_vectorcall(PyObject *type, PyObject *const *args,
size_t nargsf, PyObject *kwnames)
{
if (!_PyArg_NoKwnames("float", kwnames)) {
@ -1771,13 +1776,13 @@ float___getformat___impl(PyTypeObject *type, const char *typestr)
static PyObject *
float_getreal(PyObject *v, void *closure)
float_getreal(PyObject *v, void *Py_UNUSED(closure))
{
return float_float(v);
}
static PyObject *
float_getimag(PyObject *v, void *closure)
float_getimag(PyObject *Py_UNUSED(v), void *Py_UNUSED(closure))
{
return PyFloat_FromDouble(0.0);
}
@ -1829,11 +1834,11 @@ static PyMethodDef float_methods[] = {
static PyGetSetDef float_getset[] = {
{"real",
float_getreal, (setter)NULL,
float_getreal, NULL,
"the real part of a complex number",
NULL},
{"imag",
float_getimag, (setter)NULL,
float_getimag, NULL,
"the imaginary part of a complex number",
NULL},
{NULL} /* Sentinel */
@ -1847,10 +1852,10 @@ static PyNumberMethods float_as_number = {
float_rem, /* nb_remainder */
float_divmod, /* nb_divmod */
float_pow, /* nb_power */
(unaryfunc)float_neg, /* nb_negative */
float_neg, /* nb_negative */
float_float, /* nb_positive */
(unaryfunc)float_abs, /* nb_absolute */
(inquiry)float_bool, /* nb_bool */
float_abs, /* nb_absolute */
float_bool, /* nb_bool */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
@ -1881,16 +1886,16 @@ PyTypeObject PyFloat_Type = {
"float",
sizeof(PyFloatObject),
0,
(destructor)float_dealloc, /* tp_dealloc */
float_dealloc, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)float_repr, /* tp_repr */
float_repr, /* tp_repr */
&float_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)float_hash, /* tp_hash */
float_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
@ -1916,7 +1921,7 @@ PyTypeObject PyFloat_Type = {
0, /* tp_init */
0, /* tp_alloc */
float_new, /* tp_new */
.tp_vectorcall = (vectorcallfunc)float_vectorcall,
.tp_vectorcall = float_vectorcall,
.tp_version_tag = _Py_TYPE_VERSION_FLOAT,
};