Skip to content

Commit 8f03546

Browse files
committed
pytime: Use llround for double -> integer conversions.
This avoids compiler warnings and is probably safer from undefined behavior than the previous code. Fixes pythongh-97786.
1 parent b0f89cb commit 8f03546

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

Python/pytime.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
# include <winsock2.h> // struct timeval
55
#endif
66

7+
#include <fenv.h>
8+
79
#if defined(__APPLE__)
810
# include <mach/mach_time.h> // mach_absolute_time(), mach_timebase_info()
911

@@ -294,11 +296,13 @@ pytime_double_to_denominator(double d, time_t *sec, long *numerator,
294296
}
295297
assert(0.0 <= floatpart && floatpart < denominator);
296298

297-
if (!_Py_InIntegralTypeRange(time_t, intpart)) {
299+
feclearexcept(FE_ALL_EXCEPT);
300+
long long second = llround(intpart);
301+
if (fetestexcept(FE_INVALID) || !_Py_InIntegralTypeRange(time_t, second)) {
298302
pytime_time_t_overflow();
299303
return -1;
300304
}
301-
*sec = (time_t)intpart;
305+
*sec = (time_t)second;
302306
*numerator = (long)floatpart;
303307
assert(0 <= *numerator && *numerator < idenominator);
304308
return 0;
@@ -349,11 +353,13 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
349353
d = pytime_round(d, round);
350354
(void)modf(d, &intpart);
351355

352-
if (!_Py_InIntegralTypeRange(time_t, intpart)) {
356+
feclearexcept(FE_ALL_EXCEPT);
357+
long long second = llround(intpart);
358+
if (fetestexcept(FE_INVALID) || !_Py_InIntegralTypeRange(time_t, second)) {
353359
pytime_time_t_overflow();
354360
return -1;
355361
}
356-
*sec = (time_t)intpart;
362+
*sec = (time_t)second;
357363
return 0;
358364
}
359365
else {
@@ -515,13 +521,14 @@ pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round,
515521
d *= (double)unit_to_ns;
516522
d = pytime_round(d, round);
517523

518-
if (!_Py_InIntegralTypeRange(_PyTime_t, d)) {
524+
feclearexcept(FE_ALL_EXCEPT);
525+
long long ns = llround(d);
526+
if (fetestexcept(FE_ALL_EXCEPT)) {
519527
pytime_overflow();
520528
return -1;
521529
}
522-
_PyTime_t ns = (_PyTime_t)d;
523530

524-
*tp = pytime_from_nanoseconds(ns);
531+
*tp = pytime_from_nanoseconds((_PyTime_t)ns);
525532
return 0;
526533
}
527534

0 commit comments

Comments
 (0)