*** ./lib/mktime.c.ORIG Tue May 24 10:31:25 2016 --- ./lib/mktime.c Tue May 24 10:31:32 2016 *************** *** 17,29 **** License along with the GNU C Library; if not, see . */ ! /* Define this to 1 to have a standalone program to test this implementation of mktime. */ ! #ifndef DEBUG_MKTIME ! # define DEBUG_MKTIME 0 ! #endif ! #if !defined _LIBC && !DEBUG_MKTIME # include #endif --- 17,27 ---- License along with the GNU C Library; if not, see . */ ! /* Define this to have a standalone program to test this implementation of mktime. */ ! /* #define DEBUG_MKTIME 1 */ ! #ifndef _LIBC # include #endif *************** *** 37,112 **** #include #include - #include ! #include ! #include ! #if DEBUG_MKTIME # include # include - # include /* Make it work even if the system's libc has its own mktime routine. */ # undef mktime # define mktime my_mktime ! #endif ! /* A signed type that can represent an integer number of years ! multiplied by three times the number of seconds in a year. It is ! needed when converting a tm_year value times the number of seconds ! in a year. The factor of three comes because these products need ! to be subtracted from each other, and sometimes with an offset ! added to them, without worrying about overflow. ! Much of the code uses long_int to represent time_t values, to ! lessen the hassle of dealing with platforms where time_t is ! unsigned, and because long_int should suffice to represent all ! time_t values that mktime can generate even on platforms where ! time_t is excessively wide. */ ! #if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60 typedef long int long_int; #else typedef long long int long_int; #endif ! verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 3 / 366 / 24 / 60 / 60); /* Shift A right by B bits portably, by dividing A by 2**B and ! truncating towards minus infinity. B should be in the range 0 <= B ! <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful ! bits in a long_int. LONG_INT_BITS is at least 32. ISO C99 says that A >> B is implementation-defined if A < 0. Some implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift right in the usual way when A < 0, so SHR falls back on division if ordinary A >> B doesn't seem to be the usual signed shift. */ ! static long_int ! shr (long_int a, int b) ! { ! long_int one = 1; ! return (-one >> 1 == -1 ! ? a >> b ! : a / (one << b) - (a % (one << b) < 0)); ! } ! /* Bounds for the intersection of time_t and long_int. */ ! static long_int const mktime_min ! = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int)) ! ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t)); ! static long_int const mktime_max ! = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t) ! ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t)); ! verify (TYPE_IS_INTEGER (time_t)); #define EPOCH_YEAR 1970 #define TM_YEAR_BASE 1900 ! verify (TM_YEAR_BASE % 100 == 0); ! /* Is YEAR + TM_YEAR_BASE a leap year? */ ! static bool leapyear (long_int year) { /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. --- 35,148 ---- #include #include ! #include /* For the real memcpy prototype. */ ! #if defined DEBUG_MKTIME && DEBUG_MKTIME # include # include /* Make it work even if the system's libc has its own mktime routine. */ # undef mktime # define mktime my_mktime ! #endif /* DEBUG_MKTIME */ ! /* Some of the code in this file assumes that signed integer overflow ! silently wraps around. This assumption can't easily be programmed ! around, nor can it be checked for portably at compile-time or ! easily eliminated at run-time. ! Define WRAPV to 1 if the assumption is valid and if ! #pragma GCC optimize ("wrapv") ! does not trigger GCC bug 51793 ! . ! Otherwise, define it to 0; this forces the use of slower code that, ! while not guaranteed by the C Standard, works on all production ! platforms that we know about. */ ! #ifndef WRAPV ! # if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \ ! && defined __GLIBC__) ! # pragma GCC optimize ("wrapv") ! # define WRAPV 1 ! # else ! # define WRAPV 0 ! # endif ! #endif ! /* Verify a requirement at compile-time (unlike assert, which is runtime). */ ! #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } ! ! /* A signed type that is at least one bit wider than int. */ ! #if INT_MAX <= LONG_MAX / 2 typedef long int long_int; #else typedef long long int long_int; #endif ! verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); /* Shift A right by B bits portably, by dividing A by 2**B and ! truncating towards minus infinity. A and B should be free of side ! effects, and B should be in the range 0 <= B <= INT_BITS - 2, where ! INT_BITS is the number of useful bits in an int. GNU code can ! assume that INT_BITS is at least 32. ISO C99 says that A >> B is implementation-defined if A < 0. Some implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift right in the usual way when A < 0, so SHR falls back on division if ordinary A >> B doesn't seem to be the usual signed shift. */ + #define SHR(a, b) \ + ((-1 >> 1 == -1 \ + && (long_int) -1 >> 1 == -1 \ + && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \ + ? (a) >> (b) \ + : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) ! /* The extra casts in the following macros work around compiler bugs, ! e.g., in Cray C 5.0.3.0. */ ! /* True if the arithmetic type T is an integer type. bool counts as ! an integer. */ ! #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) ! /* True if negative values of the signed integer type T use two's ! complement, or if T is an unsigned integer type. */ ! #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) ! /* True if the arithmetic type T is signed. */ ! #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + /* The maximum and minimum values for the integer type T. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ + #define TYPE_MINIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) 0 \ + : ~ TYPE_MAXIMUM (t))) + #define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + + #ifndef TIME_T_MIN + # define TIME_T_MIN TYPE_MINIMUM (time_t) + #endif + #ifndef TIME_T_MAX + # define TIME_T_MAX TYPE_MAXIMUM (time_t) + #endif + #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) + + verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); + verify (twos_complement_arithmetic, + (TYPE_TWOS_COMPLEMENT (int) + && TYPE_TWOS_COMPLEMENT (long_int) + && TYPE_TWOS_COMPLEMENT (time_t))); + #define EPOCH_YEAR 1970 #define TM_YEAR_BASE 1900 ! verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); ! /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ ! static int leapyear (long_int year) { /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. *************** *** 130,138 **** }; ! #ifdef _LIBC ! typedef time_t mktime_offset_t; ! #else /* Portable standalone applications should supply a that declares a POSIX-compliant localtime_r, for the benefit of older implementations that lack localtime_r or have a nonstandard one. --- 166,172 ---- }; ! #ifndef _LIBC /* Portable standalone applications should supply a that declares a POSIX-compliant localtime_r, for the benefit of older implementations that lack localtime_r or have a nonstandard one. *************** *** 143,151 **** # include "mktime-internal.h" #endif ! /* Do the values A and B differ according to the rules for tm_isdst? ! A and B differ if one is zero and the other positive. */ ! static bool isdst_differ (int a, int b) { return (!a != !b) && (0 <= a) && (0 <= b); --- 177,185 ---- # include "mktime-internal.h" #endif ! /* Return 1 if the values A and B differ according to the rules for ! tm_isdst: A and B differ if one is zero and the other positive. */ ! static int isdst_differ (int a, int b) { return (!a != !b) && (0 <= a) && (0 <= b); *************** *** 156,220 **** were not adjusted between the time stamps. The YEAR values uses the same numbering as TP->tm_year. Values ! need not be in the usual range. However, YEAR1 must not overflow ! when multiplied by three times the number of seconds in a year, and ! likewise for YDAY1 and three times the number of seconds in a day. */ ! static long_int ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, int year0, int yday0, int hour0, int min0, int sec0) { ! verify (-1 / 2 == 0); /* Compute intervening leap days correctly even if year is negative. Take care to avoid integer overflow here. */ ! int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3); ! int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3); int a100 = a4 / 25 - (a4 % 25 < 0); int b100 = b4 / 25 - (b4 % 25 < 0); ! int a400 = shr (a100, 2); ! int b400 = shr (b100, 2); int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); ! /* Compute the desired time without overflowing. */ ! long_int years = year1 - year0; ! long_int days = 365 * years + yday1 - yday0 + intervening_leap_days; ! long_int hours = 24 * days + hour1 - hour0; ! long_int minutes = 60 * hours + min1 - min0; ! long_int seconds = 60 * minutes + sec1 - sec0; return seconds; } ! /* Return the average of A and B, even if A + B would overflow. ! Round toward positive infinity. */ ! static long_int ! long_int_avg (long_int a, long_int b) { ! return shr (a, 1) + shr (b, 1) + ((a | b) & 1); } /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), ! assuming that T corresponds to *TP and that no clock adjustments occurred between *TP and the desired time. ! Although T and the returned value are of type long_int, ! they represent time_t values and must be in time_t range. ! If TP is null, return a value not equal to T; this avoids false matches. ! YEAR and YDAY must not be so large that multiplying them by three times the ! number of seconds in a year (or day, respectively) would overflow long_int. ! If the returned value would be out of range, yield the minimal or ! maximal in-range value, except do not yield a value equal to T. */ ! static long_int guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, ! long_int t, const struct tm *tp) { if (tp) { ! long_int result; ! long_int d = ydhms_diff (year, yday, hour, min, sec, ! tp->tm_year, tp->tm_yday, ! tp->tm_hour, tp->tm_min, tp->tm_sec); ! if (! INT_ADD_WRAPV (t, d, &result)) ! return result; } /* Overflow occurred one way or another. Return the nearest result --- 190,293 ---- were not adjusted between the time stamps. The YEAR values uses the same numbering as TP->tm_year. Values ! need not be in the usual range. However, YEAR1 must not be less ! than 2 * INT_MIN or greater than 2 * INT_MAX. ! The result may overflow. It is the caller's responsibility to ! detect overflow. */ ! ! static time_t ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, int year0, int yday0, int hour0, int min0, int sec0) { ! verify (C99_integer_division, -1 / 2 == 0); /* Compute intervening leap days correctly even if year is negative. Take care to avoid integer overflow here. */ ! int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3); ! int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3); int a100 = a4 / 25 - (a4 % 25 < 0); int b100 = b4 / 25 - (b4 % 25 < 0); ! int a400 = SHR (a100, 2); ! int b400 = SHR (b100, 2); int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); ! /* Compute the desired time in time_t precision. Overflow might ! occur here. */ ! time_t tyear1 = year1; ! time_t years = tyear1 - year0; ! time_t days = 365 * years + yday1 - yday0 + intervening_leap_days; ! time_t hours = 24 * days + hour1 - hour0; ! time_t minutes = 60 * hours + min1 - min0; ! time_t seconds = 60 * minutes + sec1 - sec0; return seconds; } ! /* Return the average of A and B, even if A + B would overflow. */ ! static time_t ! time_t_avg (time_t a, time_t b) { ! return SHR (a, 1) + SHR (b, 1) + (a & b & 1); } + /* Return 1 if A + B does not overflow. If time_t is unsigned and if + B's top bit is set, assume that the sum represents A - -B, and + return 1 if the subtraction does not wrap around. */ + static int + time_t_add_ok (time_t a, time_t b) + { + if (! TYPE_SIGNED (time_t)) + { + time_t sum = a + b; + return (sum < a) == (TIME_T_MIDPOINT <= b); + } + else if (WRAPV) + { + time_t sum = a + b; + return (sum < a) == (b < 0); + } + else + { + time_t avg = time_t_avg (a, b); + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; + } + } + + /* Return 1 if A + B does not overflow. */ + static int + time_t_int_add_ok (time_t a, int b) + { + verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX); + if (WRAPV) + { + time_t sum = a + b; + return (sum < a) == (b < 0); + } + else + { + int a_odd = a & 1; + time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b)); + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; + } + } + /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), ! assuming that *T corresponds to *TP and that no clock adjustments occurred between *TP and the desired time. ! If TP is null, return a value not equal to *T; this avoids false matches. ! If overflow occurs, yield the minimal or maximal value, except do not ! yield a value equal to *T. */ ! static time_t guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, ! const time_t *t, const struct tm *tp) { if (tp) { ! time_t d = ydhms_diff (year, yday, hour, min, sec, ! tp->tm_year, tp->tm_yday, ! tp->tm_hour, tp->tm_min, tp->tm_sec); ! if (time_t_add_ok (*t, d)) ! return *t + d; } /* Overflow occurred one way or another. Return the nearest result *************** *** 222,272 **** if the actual difference is nonzero, as that would cause a false match; and don't oscillate between two values, as that would confuse the spring-forward gap detector. */ ! return (t < long_int_avg (mktime_min, mktime_max) ! ? (t <= mktime_min + 1 ? t + 1 : mktime_min) ! : (mktime_max - 1 <= t ? t - 1 : mktime_max)); } - /* Use CONVERT to convert T to a struct tm value in *TM. T must be in - range for time_t. Return TM if successful, NULL if T is out of - range for CONVERT. */ - static struct tm * - convert_time (struct tm *(*convert) (const time_t *, struct tm *), - long_int t, struct tm *tm) - { - time_t x = t; - return convert (&x, tm); - } - /* Use CONVERT to convert *T to a broken down time in *TP. If *T is out of range for conversion, adjust it so that ! it is the nearest in-range value and then convert that. ! A value is in range if it fits in both time_t and long_int. */ static struct tm * ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), ! long_int *t, struct tm *tp) { ! struct tm *r; ! if (*t < mktime_min) ! *t = mktime_min; ! else if (mktime_max < *t) ! *t = mktime_max; ! r = convert_time (convert, *t, tp); if (!r && *t) { ! long_int bad = *t; ! long_int ok = 0; ! /* BAD is a known unconvertible value, and OK is a known good one. Use binary search to narrow the range between BAD and OK until they differ by 1. */ ! while (true) { ! long_int mid = long_int_avg (ok, bad); ! if (mid != ok && mid != bad) ! break; ! r = convert_time (convert, mid, tp); if (r) ok = mid; else --- 295,326 ---- if the actual difference is nonzero, as that would cause a false match; and don't oscillate between two values, as that would confuse the spring-forward gap detector. */ ! return (*t < TIME_T_MIDPOINT ! ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN) ! : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX)); } /* Use CONVERT to convert *T to a broken down time in *TP. If *T is out of range for conversion, adjust it so that ! it is the nearest in-range value and then convert that. */ static struct tm * ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), ! time_t *t, struct tm *tp) { ! struct tm *r = convert (t, tp); if (!r && *t) { ! time_t bad = *t; ! time_t ok = 0; ! /* BAD is a known unconvertible time_t, and OK is a known good one. Use binary search to narrow the range between BAD and OK until they differ by 1. */ ! while (bad != ok + (bad < 0 ? -1 : 1)) { ! time_t mid = *t = time_t_avg (ok, bad); ! r = convert (t, tp); if (r) ok = mid; else *************** *** 277,283 **** { /* The last conversion attempt failed; revert to the most recent successful attempt. */ ! r = convert_time (convert, ok, tp); } } --- 331,338 ---- { /* The last conversion attempt failed; revert to the most recent successful attempt. */ ! *t = ok; ! r = convert (t, tp); } } *************** *** 284,289 **** --- 339,345 ---- return r; } + /* Convert *TP to a time_t value, inverting the monotonic and mostly-unit-linear conversion function CONVERT. Use *OFFSET to keep track of a guess at the offset of the result, *************** *** 293,301 **** time_t __mktime_internal (struct tm *tp, struct tm *(*convert) (const time_t *, struct tm *), ! mktime_offset_t *offset) { ! long_int t, gt, t0, t1, t2, dt; struct tm tm; /* The maximum number of probes (calls to CONVERT) should be enough --- 349,357 ---- time_t __mktime_internal (struct tm *tp, struct tm *(*convert) (const time_t *, struct tm *), ! time_t *offset) { ! time_t t, gt, t0, t1, t2; struct tm tm; /* The maximum number of probes (calls to CONVERT) should be enough *************** *** 325,331 **** long_int year = lyear_requested + mon_years; /* The other values need not be in range: ! the remaining code handles overflows correctly. */ /* Calculate day of year from year, month, and day of month. The result need not be in range. */ --- 381,389 ---- long_int year = lyear_requested + mon_years; /* The other values need not be in range: ! the remaining code handles minor overflows correctly, ! assuming int and time_t arithmetic wraps around. ! Major overflows are caught at the end. */ /* Calculate day of year from year, month, and day of month. The result need not be in range. */ *************** *** 335,341 **** long_int lmday = mday; long_int yday = mon_yday + lmday; ! int negative_offset_guess; int sec_requested = sec; --- 393,399 ---- long_int lmday = mday; long_int yday = mon_yday + lmday; ! time_t guessed_offset = *offset; int sec_requested = sec; *************** *** 352,365 **** /* Invert CONVERT by probing. First assume the same offset as last time. */ - INT_SUBTRACT_WRAPV (0, *offset, &negative_offset_guess); t0 = ydhms_diff (year, yday, hour, min, sec, ! EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess); /* Repeatedly use the error to improve the guess. */ for (t = t1 = t2 = t0, dst2 = 0; ! (gt = guess_time_tm (year, yday, hour, min, sec, t, ranged_convert (convert, &t, &tm)), t != gt); t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) --- 410,480 ---- /* Invert CONVERT by probing. First assume the same offset as last time. */ t0 = ydhms_diff (year, yday, hour, min, sec, ! EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset); + if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + { + /* time_t isn't large enough to rule out overflows, so check + for major overflows. A gross check suffices, since if t0 + has overflowed, it is off by a multiple of TIME_T_MAX - + TIME_T_MIN + 1. So ignore any component of the difference + that is bounded by a small value. */ + + /* Approximate log base 2 of the number of time units per + biennium. A biennium is 2 years; use this unit instead of + years to avoid integer overflow. For example, 2 average + Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds, + which is 63113904 seconds, and rint (log2 (63113904)) is + 26. */ + int ALOG2_SECONDS_PER_BIENNIUM = 26; + int ALOG2_MINUTES_PER_BIENNIUM = 20; + int ALOG2_HOURS_PER_BIENNIUM = 14; + int ALOG2_DAYS_PER_BIENNIUM = 10; + int LOG2_YEARS_PER_BIENNIUM = 1; + + int approx_requested_biennia = + (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM) + - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM) + + SHR (mday, ALOG2_DAYS_PER_BIENNIUM) + + SHR (hour, ALOG2_HOURS_PER_BIENNIUM) + + SHR (min, ALOG2_MINUTES_PER_BIENNIUM) + + (LEAP_SECONDS_POSSIBLE + ? 0 + : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM))); + + int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); + int diff = approx_biennia - approx_requested_biennia; + int approx_abs_diff = diff < 0 ? -1 - diff : diff; + + /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously + gives a positive value of 715827882. Setting a variable + first then doing math on it seems to work. + (ghazi@caip.rutgers.edu) */ + time_t time_t_max = TIME_T_MAX; + time_t time_t_min = TIME_T_MIN; + time_t overflow_threshold = + (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM; + + if (overflow_threshold < approx_abs_diff) + { + /* Overflow occurred. Try repairing it; this might work if + the time zone offset is enough to undo the overflow. */ + time_t repaired_t0 = -1 - t0; + approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); + diff = approx_biennia - approx_requested_biennia; + approx_abs_diff = diff < 0 ? -1 - diff : diff; + if (overflow_threshold < approx_abs_diff) + return -1; + guessed_offset += repaired_t0 - t0; + t0 = repaired_t0; + } + } + /* Repeatedly use the error to improve the guess. */ for (t = t1 = t2 = t0, dst2 = 0; ! (gt = guess_time_tm (year, yday, hour, min, sec, &t, ranged_convert (convert, &t, &tm)), t != gt); t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) *************** *** 416,457 **** for (delta = stride; delta < delta_bound; delta += stride) for (direction = -1; direction <= 1; direction += 2) ! { ! long_int ot; ! if (! INT_ADD_WRAPV (t, delta * direction, &ot)) ! { ! struct tm otm; ! ranged_convert (convert, &ot, &otm); ! if (! isdst_differ (isdst, otm.tm_isdst)) ! { ! /* We found the desired tm_isdst. ! Extrapolate back to the desired time. */ ! t = guess_time_tm (year, yday, hour, min, sec, ot, &otm); ! ranged_convert (convert, &t, &tm); ! goto offset_found; ! } ! } ! } } offset_found: ! /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS. ! This is just a heuristic to speed up the next mktime call, and ! correctness is unaffected if integer overflow occurs here. */ ! INT_SUBTRACT_WRAPV (t, t0, &dt); ! INT_SUBTRACT_WRAPV (dt, negative_offset_guess, offset); if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) { /* Adjust time to reflect the tm_sec requested, not the normalized value. Also, repair any damage from a false match due to a leap second. */ ! long_int sec_adjustment = sec == 0 && tm.tm_sec == 60; ! sec_adjustment -= sec; ! sec_adjustment += sec_requested; ! if (INT_ADD_WRAPV (t, sec_adjustment, &t) ! || ! (mktime_min <= t && t <= mktime_max) ! || ! convert_time (convert, t, &tm)) return -1; } *tp = tm; --- 531,569 ---- for (delta = stride; delta < delta_bound; delta += stride) for (direction = -1; direction <= 1; direction += 2) ! if (time_t_int_add_ok (t, delta * direction)) ! { ! time_t ot = t + delta * direction; ! struct tm otm; ! ranged_convert (convert, &ot, &otm); ! if (! isdst_differ (isdst, otm.tm_isdst)) ! { ! /* We found the desired tm_isdst. ! Extrapolate back to the desired time. */ ! t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); ! ranged_convert (convert, &t, &tm); ! goto offset_found; ! } ! } } offset_found: ! *offset = guessed_offset + t - t0; if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) { /* Adjust time to reflect the tm_sec requested, not the normalized value. Also, repair any damage from a false match due to a leap second. */ ! int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; ! if (! time_t_int_add_ok (t, sec_requested)) return -1; + t1 = t + sec_requested; + if (! time_t_int_add_ok (t1, sec_adjustment)) + return -1; + t2 = t1 + sec_adjustment; + if (! convert (&t2, &tm)) + return -1; + t = t2; } *tp = tm; *************** *** 459,465 **** } ! static mktime_offset_t localtime_offset; /* Convert *TP to a time_t value. */ time_t --- 571,581 ---- } ! /* FIXME: This should use a signed type wide enough to hold any UTC ! offset in seconds. 'int' should be good enough for GNU code. We ! can't fix this unilaterally though, as other modules invoke ! __mktime_internal. */ ! static time_t localtime_offset; /* Convert *TP to a time_t value. */ time_t *************** *** 484,490 **** libc_hidden_weak (timelocal) #endif ! #if DEBUG_MKTIME static int not_equal_tm (const struct tm *a, const struct tm *b) --- 600,606 ---- libc_hidden_weak (timelocal) #endif ! #if defined DEBUG_MKTIME && DEBUG_MKTIME static int not_equal_tm (const struct tm *a, const struct tm *b) *************** *** 536,549 **** time_t tk, tl, tl1; char trailer; - /* Sanity check, plus call tzset. */ - tl = 0; - if (! localtime (&tl)) - { - printf ("localtime (0) fails\n"); - status = 1; - } - if ((argc == 3 || argc == 4) && (sscanf (argv[1], "%d-%d-%d%c", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) --- 652,657 ---- *************** *** 557,563 **** tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); tmk = tm; tl = mktime (&tmk); ! lt = localtime_r (&tl, &tml); printf ("mktime returns %ld == ", (long int) tl); print_tm (&tmk); printf ("\n"); --- 665,676 ---- tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); tmk = tm; tl = mktime (&tmk); ! lt = localtime (&tl); ! if (lt) ! { ! tml = *lt; ! lt = &tml; ! } printf ("mktime returns %ld == ", (long int) tl); print_tm (&tmk); printf ("\n"); *************** *** 572,587 **** if (argc == 4) for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) { ! lt = localtime_r (&tl, &tml); if (lt) { ! tmk = tml; tk = mktime (&tmk); status |= check_result (tk, tmk, tl, &tml); } else { ! printf ("localtime_r (%ld) yields 0\n", (long int) tl); status = 1; } tl1 = tl + by; --- 685,700 ---- if (argc == 4) for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) { ! lt = localtime (&tl); if (lt) { ! tmk = tml = *lt; tk = mktime (&tmk); status |= check_result (tk, tmk, tl, &tml); } else { ! printf ("localtime (%ld) yields 0\n", (long int) tl); status = 1; } tl1 = tl + by; *************** *** 592,607 **** for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) { /* Null benchmark. */ ! lt = localtime_r (&tl, &tml); if (lt) { ! tmk = tml; tk = tl; status |= check_result (tk, tmk, tl, &tml); } else { ! printf ("localtime_r (%ld) yields 0\n", (long int) tl); status = 1; } tl1 = tl + by; --- 705,720 ---- for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) { /* Null benchmark. */ ! lt = localtime (&tl); if (lt) { ! tmk = tml = *lt; tk = tl; status |= check_result (tk, tmk, tl, &tml); } else { ! printf ("localtime (%ld) yields 0\n", (long int) tl); status = 1; } tl1 = tl + by;