[PROPOSED 1/2] Move MKTIME_MIGHT_OVERFLOW definition
* private.h (MKTIME_FITS_IN, MKTIME_MIGHT_OVERFLOW): Move definitions from here ... * strftime.c: ... to here, as it’s the only file needing them. --- private.h | 49 ------------------------------------------------- strftime.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/private.h b/private.h index fc0b8755..95ab2e1d 100644 --- a/private.h +++ b/private.h @@ -914,55 +914,6 @@ enum { SIGNED_PADDING_CHECK_NEEDED = true }; static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED || TIME_T_MAX >> (TYPE_BIT(time_t) - 2) == 1); -/* If true, the value returned by an idealized unlimited-range mktime - always fits into an integer type with bounds MIN and MAX. - If false, the value might not fit. - This macro is usable in #if if its arguments are. - Add or subtract 2**31 - 1 for the maximum UT offset allowed in a TZif file, - divide by the maximum number of non-leap seconds in a year, - divide again by two just to be safe, - and account for the tm_year origin (1900) and time_t origin (1970). */ -#define MKTIME_FITS_IN(min, max) \ - ((min) < 0 \ - && ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \ - && INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900) - -/* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow - or if it is not known whether mktime can fail, - and is false if mktime definitely cannot fail. - This macro is usable in #if, and so does not use TIME_T_MAX or sizeof. - If the builder has not configured this macro, guess based on what - known platforms do. When in doubt, guess true. */ -#ifndef MKTIME_MIGHT_OVERFLOW -# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ -# include <sys/param.h> -# endif -# if ((/* The following heuristics assume native time_t. */ \ - defined_time_tz) \ - || ((/* Traditional time_t is 'long', so if 'long' is not wide enough \ - assume overflow unless we're on a known-safe host. */ \ - !MKTIME_FITS_IN(LONG_MIN, LONG_MAX)) \ - && (/* GNU C Library 2.29 (2019-02-01) and later has 64-bit time_t \ - if __TIMESIZE is 64. */ \ - !defined __TIMESIZE || __TIMESIZE < 64) \ - && (/* FreeBSD 12 r320347 (__FreeBSD_version 1200036; 2017-06-26), \ - and later has 64-bit time_t on all platforms but i386 which \ - is currently scheduled for end-of-life on 2028-11-30. */ \ - !defined __FreeBSD_version || __FreeBSD_version < 1200036 \ - || defined __i386) \ - && (/* NetBSD 6.0 (2012-10-17) and later has 64-bit time_t. */ \ - !defined __NetBSD_Version__ || __NetBSD_Version__ < 600000000) \ - && (/* OpenBSD 5.5 (2014-05-01) and later has 64-bit time_t. */ \ - !defined OpenBSD || OpenBSD < 201405))) -# define MKTIME_MIGHT_OVERFLOW true -# else -# define MKTIME_MIGHT_OVERFLOW false -# endif -#endif -/* Check that MKTIME_MIGHT_OVERFLOW is consistent with time_t's range. */ -static_assert(MKTIME_MIGHT_OVERFLOW - || MKTIME_FITS_IN(TIME_T_MIN, TIME_T_MAX)); - /* ** 302 / 1000 is log10(2.0) rounded up. ** Subtract one for the sign bit if the type is signed; diff --git a/strftime.c b/strftime.c index 7be94de3..fc0c87d2 100644 --- a/strftime.c +++ b/strftime.c @@ -39,6 +39,55 @@ #include <locale.h> #include <stdio.h> +/* If true, the value returned by an idealized unlimited-range mktime + always fits into an integer type with bounds MIN and MAX. + If false, the value might not fit. + This macro is usable in #if if its arguments are. + Add or subtract 2**31 - 1 for the maximum UT offset allowed in a TZif file, + divide by the maximum number of non-leap seconds in a year, + divide again by two just to be safe, + and account for the tm_year origin (1900) and time_t origin (1970). */ +#define MKTIME_FITS_IN(min, max) \ + ((min) < 0 \ + && ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \ + && INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900) + +/* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow + or if it is not known whether mktime can fail, + and is false if mktime definitely cannot fail. + This macro is usable in #if, and so does not use TIME_T_MAX or sizeof. + If the builder has not configured this macro, guess based on what + known platforms do. When in doubt, guess true. */ +#ifndef MKTIME_MIGHT_OVERFLOW +# if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ +# include <sys/param.h> +# endif +# if ((/* The following heuristics assume native time_t. */ \ + defined_time_tz) \ + || ((/* Traditional time_t is 'long', so if 'long' is not wide enough \ + assume overflow unless we're on a known-safe host. */ \ + !MKTIME_FITS_IN(LONG_MIN, LONG_MAX)) \ + && (/* GNU C Library 2.29 (2019-02-01) and later has 64-bit time_t \ + if __TIMESIZE is 64. */ \ + !defined __TIMESIZE || __TIMESIZE < 64) \ + && (/* FreeBSD 12 r320347 (__FreeBSD_version 1200036; 2017-06-26), \ + and later has 64-bit time_t on all platforms but i386 which \ + is currently scheduled for end-of-life on 2028-11-30. */ \ + !defined __FreeBSD_version || __FreeBSD_version < 1200036 \ + || defined __i386) \ + && (/* NetBSD 6.0 (2012-10-17) and later has 64-bit time_t. */ \ + !defined __NetBSD_Version__ || __NetBSD_Version__ < 600000000) \ + && (/* OpenBSD 5.5 (2014-05-01) and later has 64-bit time_t. */ \ + !defined OpenBSD || OpenBSD < 201405))) +# define MKTIME_MIGHT_OVERFLOW true +# else +# define MKTIME_MIGHT_OVERFLOW false +# endif +#endif +/* Check that MKTIME_MIGHT_OVERFLOW is consistent with time_t's range. */ +static_assert(MKTIME_MIGHT_OVERFLOW + || MKTIME_FITS_IN(TIME_T_MIN, TIME_T_MAX)); + #if MKTIME_MIGHT_OVERFLOW /* Do this after system includes as it redefines time_t, mktime, timeoff. */ # define USE_TIMEX_T true -- 2.47.0
* private.h (timeoff): Don’t worry about USE_TIMEX_T. --- private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/private.h b/private.h index 95ab2e1d..da6dc790 100644 --- a/private.h +++ b/private.h @@ -946,7 +946,7 @@ static_assert(! TYPE_SIGNED(time_t) || ! SIGNED_PADDING_CHECK_NEEDED /* strftime.c sometimes needs access to timeoff if it is not already public. tz_private_timeoff should be used only by localtime.c and strftime.c. */ -#if (!defined EXTERN_TIMEOFF && ! (defined USE_TIMEX_T && USE_TIMEX_T) \ +#if (!defined EXTERN_TIMEOFF \ && defined TM_GMTOFF && (200809 < _POSIX_VERSION || ! UNINIT_TRAP)) # ifndef timeoff # define timeoff tz_private_timeoff -- 2.47.0
participants (1)
-
Paul Eggert