Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix compiler warnings in pytime.c
  • Loading branch information
mdickinson committed Feb 11, 2023
commit 622ec0afd1a6f1a607a542a861fdd21237a16fb7
35 changes: 29 additions & 6 deletions Python/pytime.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "Python.h"
#include "pycore_pymath.h" // _Py_InIntegralTypeRange()
#ifdef MS_WINDOWS
# include <winsock2.h> // struct timeval
#endif
Expand Down Expand Up @@ -41,6 +40,14 @@
# error "unsupported time_t size"
#endif

#if PY_TIME_T_MAX + PY_TIME_T_MIN != -1
Comment thread
mdickinson marked this conversation as resolved.
# error "time_t is not a two's complement integer type"
#endif

#if _PyTime_MIN + _PyTime_MAX != -1
# error "_PyTime_t is not a two's complement integer type"
#endif


static void
pytime_time_t_overflow(void)
Expand Down Expand Up @@ -294,7 +301,19 @@ pytime_double_to_denominator(double d, time_t *sec, long *numerator,
}
assert(0.0 <= floatpart && floatpart < denominator);

if (!_Py_InIntegralTypeRange(time_t, intpart)) {
/*
Conversion of an out-of-range value to time_t gives undefined behaviour
(C99 §6.3.1.4p1), so we must guard against it. However, checking that
`intpart` is in range is delicate: the obvious expression `intpart <=
PY_TIME_T_MAX` will first convert the value `PY_TIME_T_MAX` to a double,
potentially changing its value and leading to us failing to catch some
UB-inducing values. The code below works correctly under the mild
assumption that time_t is a two's complement integer type with no trap
representation, and that `PY_TIME_T_MIN` is within the representable
range of a C double.
*/
assert(fmod(intpart, 1.0) == 0.0);
if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
Comment thread
gpshead marked this conversation as resolved.
pytime_time_t_overflow();
return -1;
}
Expand Down Expand Up @@ -349,7 +368,9 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round)
d = pytime_round(d, round);
(void)modf(d, &intpart);

if (!_Py_InIntegralTypeRange(time_t, intpart)) {
/* See comments in pytime_double_to_denominator */
assert(fmod(intpart, 1.0) == 0.0);
if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) {
pytime_time_t_overflow();
return -1;
}
Expand Down Expand Up @@ -515,8 +536,10 @@ pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round,
d *= (double)unit_to_ns;
d = pytime_round(d, round);

if (!_Py_InIntegralTypeRange(_PyTime_t, d)) {
pytime_overflow();
/* See comments in pytime_double_to_denominator */
assert(fmod(d, 1.0) == 0.0);
if (!((double)_PyTime_MIN <= d && d < -(double)_PyTime_MIN)) {
pytime_time_t_overflow();
return -1;
}
_PyTime_t ns = (_PyTime_t)d;
Expand Down Expand Up @@ -910,7 +933,7 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc)
info->monotonic = 0;
info->adjustable = 1;
if (clock_getres(CLOCK_REALTIME, &res) == 0) {
info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
info->resolution = (double)res.tv_sec + (double)res.tv_nsec * 1e-9;
Comment thread
abalkin marked this conversation as resolved.
}
else {
info->resolution = 1e-9;
Expand Down