bpo-31373: fix undefined floating-point demotions (#3396)

This commit is contained in:
Benjamin Peterson 2017-09-07 11:13:59 -07:00 committed by GitHub
parent c988ae01fe
commit a853a8ba78
5 changed files with 51 additions and 30 deletions

View file

@ -4,6 +4,7 @@
#include "Python.h"
#include <ctype.h>
#include <float.h>
#ifdef __cplusplus
@ -858,6 +859,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
double dval = PyFloat_AsDouble(arg);
if (PyErr_Occurred())
RETURN_ERR_OCCURRED;
else if (dval > FLT_MAX)
*p = (float)INFINITY;
else if (dval < -FLT_MAX)
*p = (float)-INFINITY;
else
*p = (float) dval;
break;

View file

@ -97,7 +97,7 @@ static int
_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
double denominator, _PyTime_round_t round)
{
double intpart, err;
double intpart;
/* volatile avoids optimization changing how numbers are rounded */
volatile double floatpart;
@ -115,14 +115,13 @@ _PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator,
}
assert(0.0 <= floatpart && floatpart < denominator);
*sec = (time_t)intpart;
*numerator = (long)floatpart;
err = intpart - (double)*sec;
if (err <= -1.0 || err >= 1.0) {
if (!_Py_InIntegralTypeRange(time_t, intpart)) {
error_time_t_overflow();
return -1;
}
*sec = (time_t)intpart;
*numerator = (long)floatpart;
return 0;
}
@ -150,7 +149,7 @@ int
_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
{
if (PyFloat_Check(obj)) {
double intpart, err;
double intpart;
/* volatile avoids optimization changing how numbers are rounded */
volatile double d;
@ -158,12 +157,11 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
d = _PyTime_Round(d, round);
(void)modf(d, &intpart);
*sec = (time_t)intpart;
err = intpart - (double)*sec;
if (err <= -1.0 || err >= 1.0) {
if (!_Py_InIntegralTypeRange(time_t, intpart)) {
error_time_t_overflow();
return -1;
}
*sec = (time_t)intpart;
return 0;
}
else {
@ -180,7 +178,9 @@ _PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec,
{
int res;
res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round);
assert(0 <= *nsec && *nsec < SEC_TO_NS);
if (res == 0) {
assert(0 <= *nsec && *nsec < SEC_TO_NS);
}
return res;
}
@ -190,7 +190,9 @@ _PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec,
{
int res;
res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round);
assert(0 <= *usec && *usec < SEC_TO_US);
if (res == 0) {
assert(0 <= *usec && *usec < SEC_TO_US);
}
return res;
}
@ -276,7 +278,6 @@ static int
_PyTime_FromFloatObject(_PyTime_t *t, double value, _PyTime_round_t round,
long unit_to_ns)
{
double err;
/* volatile avoids optimization changing how numbers are rounded */
volatile double d;
@ -285,12 +286,11 @@ _PyTime_FromFloatObject(_PyTime_t *t, double value, _PyTime_round_t round,
d *= (double)unit_to_ns;
d = _PyTime_Round(d, round);
*t = (_PyTime_t)d;
err = d - (double)*t;
if (fabs(err) >= 1.0) {
if (!_Py_InIntegralTypeRange(_PyTime_t, d)) {
_PyTime_overflow();
return -1;
}
*t = (_PyTime_t)d;
return 0;
}