@@ -3908,19 +3908,29 @@ math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps)
39083908 return NULL ;
39093909 }
39103910
3911- uint64_t usteps = PyLong_AsUnsignedLongLong (steps );
3911+ unsigned long long usteps_ull = PyLong_AsUnsignedLongLong (steps );
39123912 // Conveniently, uint64_t and double have the same number of bits
39133913 // on all the platforms we care about.
39143914 // So if an overflow occurs, we can just use UINT64_MAX.
3915- if (usteps == (unsigned long long )-1 && PyErr_Occurred ()) {
3916- if (!PyErr_ExceptionMatches (PyExc_OverflowError )) {
3917- Py_DECREF (steps );
3918- return NULL ;
3915+ Py_DECREF (steps );
3916+ if (usteps_ull >= UINT64_MAX ) {
3917+ // This branch includes the case where an error occurred, since
3918+ // (unsigned long long)(-1) = ULLONG_MAX >= UINT64_MAX. Note that
3919+ // usteps_ull can be strictly larger than UINT64_MAX on a machine
3920+ // where unsigned long long has width > 64 bits.
3921+ if (PyErr_Occurred ()) {
3922+ if (PyErr_ExceptionMatches (PyExc_OverflowError )) {
3923+ PyErr_Clear ();
3924+ }
3925+ else {
3926+ return NULL ;
3927+ }
39193928 }
3920- PyErr_Clear ();
3921- usteps = UINT64_MAX ;
3929+ usteps_ull = UINT64_MAX ;
39223930 }
3923- Py_DECREF (steps );
3931+ assert (usteps_ull <= UINT64_MAX );
3932+ uint64_t usteps = (uint64_t )usteps_ull ;
3933+
39243934 if (usteps == 0 ) {
39253935 return PyFloat_FromDouble (x );
39263936 }
@@ -3937,7 +3947,7 @@ math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps)
39373947 // would be a "mixed-endian" double.)
39383948 union pun {double f ; uint64_t i ;};
39393949 union pun ux = {x }, uy = {y };
3940- if (ux .i == uy .i ) {
3950+ if (ux .i == uy .i ) {
39413951 return PyFloat_FromDouble (x );
39423952 }
39433953
0 commit comments