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