aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mktime.c
diff options
context:
space:
mode:
authorPaul Eggert2016-05-01 18:36:38 -0700
committerPaul Eggert2016-05-01 18:37:01 -0700
commit3707f609cb8017371610a5e2233bd8478416217c (patch)
treefc9ecf2d9754bf95cc33bd9319871d5ebd866fa1 /lib/mktime.c
parent13f4efb0fd5573255c694607552532788ba31c95 (diff)
downloademacs-3707f609cb8017371610a5e2233bd8478416217c.tar.gz
emacs-3707f609cb8017371610a5e2233bd8478416217c.zip
Sync from gnulib
This incorporates: 2016-05-01 mktime: port to stricter signed overflow checking 2016-05-01 mktime: speed up DEBUG_MKTIME benchmarks 2016-05-01 mktime: resurrect DEBUG_MKTIME testing 2016-05-01 mktime: simplify DEBUG_MKTIME 2016-05-01 Port mktime_internal offset to unsigned time_t 2016-04-27 xstrtol: prohibit monstrosities like "1bB" 2016-04-13 mktime: improve integer overflow checking 2016-04-13 intprops: check two's complement assumption 2016-04-13 intprops, mktime, strtol: assume two's complement * lib/intprops.h, lib/mktime-internal.h, lib/mktime.c: * lib/strtol.c, lib/timegm.c, m4/mktime.m4, m4/std-gnu11.m4: Copy from gnulib.
Diffstat (limited to 'lib/mktime.c')
-rw-r--r--lib/mktime.c461
1 files changed, 174 insertions, 287 deletions
diff --git a/lib/mktime.c b/lib/mktime.c
index c9738d0daf9..419a177c018 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -17,11 +17,13 @@
17 License along with the GNU C Library; if not, see 17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
19 19
20/* Define this to have a standalone program to test this implementation of 20/* Define this to 1 to have a standalone program to test this implementation of
21 mktime. */ 21 mktime. */
22/* #define DEBUG_MKTIME 1 */ 22#ifndef DEBUG_MKTIME
23# define DEBUG_MKTIME 0
24#endif
23 25
24#ifndef _LIBC 26#if !defined _LIBC && !DEBUG_MKTIME
25# include <config.h> 27# include <config.h>
26#endif 28#endif
27 29
@@ -35,114 +37,76 @@
35#include <time.h> 37#include <time.h>
36 38
37#include <limits.h> 39#include <limits.h>
40#include <stdbool.h>
38 41
39#include <string.h> /* For the real memcpy prototype. */ 42#include <intprops.h>
43#include <verify.h>
40 44
41#if defined DEBUG_MKTIME && DEBUG_MKTIME 45#if DEBUG_MKTIME
42# include <stdio.h> 46# include <stdio.h>
43# include <stdlib.h> 47# include <stdlib.h>
48# include <string.h>
44/* Make it work even if the system's libc has its own mktime routine. */ 49/* Make it work even if the system's libc has its own mktime routine. */
45# undef mktime 50# undef mktime
46# define mktime my_mktime 51# define mktime my_mktime
47#endif /* DEBUG_MKTIME */
48
49/* Some of the code in this file assumes that signed integer overflow
50 silently wraps around. This assumption can't easily be programmed
51 around, nor can it be checked for portably at compile-time or
52 easily eliminated at run-time.
53
54 Define WRAPV to 1 if the assumption is valid and if
55 #pragma GCC optimize ("wrapv")
56 does not trigger GCC bug 51793
57 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
58 Otherwise, define it to 0; this forces the use of slower code that,
59 while not guaranteed by the C Standard, works on all production
60 platforms that we know about. */
61#ifndef WRAPV
62# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
63 && defined __GLIBC__)
64# pragma GCC optimize ("wrapv")
65# define WRAPV 1
66# else
67# define WRAPV 0
68# endif
69#endif 52#endif
70 53
71/* Verify a requirement at compile-time (unlike assert, which is runtime). */ 54/* A signed type that can represent an integer number of years
72#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } 55 multiplied by three times the number of seconds in a year. It is
56 needed when converting a tm_year value times the number of seconds
57 in a year. The factor of three comes because these products need
58 to be subtracted from each other, and sometimes with an offset
59 added to them, without worrying about overflow.
73 60
74/* A signed type that is at least one bit wider than int. */ 61 Much of the code uses long_int to represent time_t values, to
75#if INT_MAX <= LONG_MAX / 2 62 lessen the hassle of dealing with platforms where time_t is
63 unsigned, and because long_int should suffice to represent all
64 time_t values that mktime can generate even on platforms where
65 time_t is excessively wide. */
66
67#if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60
76typedef long int long_int; 68typedef long int long_int;
77#else 69#else
78typedef long long int long_int; 70typedef long long int long_int;
79#endif 71#endif
80verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); 72verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 3 / 366 / 24 / 60 / 60);
81 73
82/* Shift A right by B bits portably, by dividing A by 2**B and 74/* Shift A right by B bits portably, by dividing A by 2**B and
83 truncating towards minus infinity. A and B should be free of side 75 truncating towards minus infinity. B should be in the range 0 <= B
84 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where 76 <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful
85 INT_BITS is the number of useful bits in an int. GNU code can 77 bits in a long_int. LONG_INT_BITS is at least 32.
86 assume that INT_BITS is at least 32.
87 78
88 ISO C99 says that A >> B is implementation-defined if A < 0. Some 79 ISO C99 says that A >> B is implementation-defined if A < 0. Some
89 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift 80 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
90 right in the usual way when A < 0, so SHR falls back on division if 81 right in the usual way when A < 0, so SHR falls back on division if
91 ordinary A >> B doesn't seem to be the usual signed shift. */ 82 ordinary A >> B doesn't seem to be the usual signed shift. */
92#define SHR(a, b) \
93 ((-1 >> 1 == -1 \
94 && (long_int) -1 >> 1 == -1 \
95 && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \
96 ? (a) >> (b) \
97 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
98
99/* The extra casts in the following macros work around compiler bugs,
100 e.g., in Cray C 5.0.3.0. */
101
102/* True if the arithmetic type T is an integer type. bool counts as
103 an integer. */
104#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
105
106/* True if negative values of the signed integer type T use two's
107 complement, or if T is an unsigned integer type. */
108#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
109
110/* True if the arithmetic type T is signed. */
111#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
112
113/* The maximum and minimum values for the integer type T. These
114 macros have undefined behavior if T is signed and has padding bits.
115 If this is a problem for you, please let us know how to fix it for
116 your host. */
117#define TYPE_MINIMUM(t) \
118 ((t) (! TYPE_SIGNED (t) \
119 ? (t) 0 \
120 : ~ TYPE_MAXIMUM (t)))
121#define TYPE_MAXIMUM(t) \
122 ((t) (! TYPE_SIGNED (t) \
123 ? (t) -1 \
124 : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
125
126#ifndef TIME_T_MIN
127# define TIME_T_MIN TYPE_MINIMUM (time_t)
128#endif
129#ifndef TIME_T_MAX
130# define TIME_T_MAX TYPE_MAXIMUM (time_t)
131#endif
132#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
133 83
134verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); 84static long_int
135verify (twos_complement_arithmetic, 85shr (long_int a, int b)
136 (TYPE_TWOS_COMPLEMENT (int) 86{
137 && TYPE_TWOS_COMPLEMENT (long_int) 87 long_int one = 1;
138 && TYPE_TWOS_COMPLEMENT (time_t))); 88 return (-one >> 1 == -1
89 ? a >> b
90 : a / (one << b) - (a % (one << b) < 0));
91}
92
93/* Bounds for the intersection of time_t and long_int. */
94
95static long_int const mktime_min
96 = ((TYPE_SIGNED (time_t) && TYPE_MINIMUM (time_t) < TYPE_MINIMUM (long_int))
97 ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (time_t));
98static long_int const mktime_max
99 = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (time_t)
100 ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (time_t));
101
102verify (TYPE_IS_INTEGER (time_t));
139 103
140#define EPOCH_YEAR 1970 104#define EPOCH_YEAR 1970
141#define TM_YEAR_BASE 1900 105#define TM_YEAR_BASE 1900
142verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); 106verify (TM_YEAR_BASE % 100 == 0);
143 107
144/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ 108/* Is YEAR + TM_YEAR_BASE a leap year? */
145static int 109static bool
146leapyear (long_int year) 110leapyear (long_int year)
147{ 111{
148 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. 112 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
@@ -166,7 +130,9 @@ const unsigned short int __mon_yday[2][13] =
166 }; 130 };
167 131
168 132
169#ifndef _LIBC 133#ifdef _LIBC
134typedef time_t mktime_offset_t;
135#else
170/* Portable standalone applications should supply a <time.h> that 136/* Portable standalone applications should supply a <time.h> that
171 declares a POSIX-compliant localtime_r, for the benefit of older 137 declares a POSIX-compliant localtime_r, for the benefit of older
172 implementations that lack localtime_r or have a nonstandard one. 138 implementations that lack localtime_r or have a nonstandard one.
@@ -177,9 +143,9 @@ const unsigned short int __mon_yday[2][13] =
177# include "mktime-internal.h" 143# include "mktime-internal.h"
178#endif 144#endif
179 145
180/* Return 1 if the values A and B differ according to the rules for 146/* Do the values A and B differ according to the rules for tm_isdst?
181 tm_isdst: A and B differ if one is zero and the other positive. */ 147 A and B differ if one is zero and the other positive. */
182static int 148static bool
183isdst_differ (int a, int b) 149isdst_differ (int a, int b)
184{ 150{
185 return (!a != !b) && (0 <= a) && (0 <= b); 151 return (!a != !b) && (0 <= a) && (0 <= b);
@@ -190,104 +156,65 @@ isdst_differ (int a, int b)
190 were not adjusted between the time stamps. 156 were not adjusted between the time stamps.
191 157
192 The YEAR values uses the same numbering as TP->tm_year. Values 158 The YEAR values uses the same numbering as TP->tm_year. Values
193 need not be in the usual range. However, YEAR1 must not be less 159 need not be in the usual range. However, YEAR1 must not overflow
194 than 2 * INT_MIN or greater than 2 * INT_MAX. 160 when multiplied by three times the number of seconds in a year, and
161 likewise for YDAY1 and three times the number of seconds in a day. */
195 162
196 The result may overflow. It is the caller's responsibility to 163static long_int
197 detect overflow. */
198
199static time_t
200ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, 164ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
201 int year0, int yday0, int hour0, int min0, int sec0) 165 int year0, int yday0, int hour0, int min0, int sec0)
202{ 166{
203 verify (C99_integer_division, -1 / 2 == 0); 167 verify (-1 / 2 == 0);
204 168
205 /* Compute intervening leap days correctly even if year is negative. 169 /* Compute intervening leap days correctly even if year is negative.
206 Take care to avoid integer overflow here. */ 170 Take care to avoid integer overflow here. */
207 int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3); 171 int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3);
208 int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3); 172 int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3);
209 int a100 = a4 / 25 - (a4 % 25 < 0); 173 int a100 = a4 / 25 - (a4 % 25 < 0);
210 int b100 = b4 / 25 - (b4 % 25 < 0); 174 int b100 = b4 / 25 - (b4 % 25 < 0);
211 int a400 = SHR (a100, 2); 175 int a400 = shr (a100, 2);
212 int b400 = SHR (b100, 2); 176 int b400 = shr (b100, 2);
213 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); 177 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
214 178
215 /* Compute the desired time in time_t precision. Overflow might 179 /* Compute the desired time without overflowing. */
216 occur here. */ 180 long_int years = year1 - year0;
217 time_t tyear1 = year1; 181 long_int days = 365 * years + yday1 - yday0 + intervening_leap_days;
218 time_t years = tyear1 - year0; 182 long_int hours = 24 * days + hour1 - hour0;
219 time_t days = 365 * years + yday1 - yday0 + intervening_leap_days; 183 long_int minutes = 60 * hours + min1 - min0;
220 time_t hours = 24 * days + hour1 - hour0; 184 long_int seconds = 60 * minutes + sec1 - sec0;
221 time_t minutes = 60 * hours + min1 - min0;
222 time_t seconds = 60 * minutes + sec1 - sec0;
223 return seconds; 185 return seconds;
224} 186}
225 187
226/* Return the average of A and B, even if A + B would overflow. */ 188/* Return the average of A and B, even if A + B would overflow.
227static time_t 189 Round toward positive infinity. */
228time_t_avg (time_t a, time_t b) 190static long_int
191long_int_avg (long_int a, long_int b)
229{ 192{
230 return SHR (a, 1) + SHR (b, 1) + (a & b & 1); 193 return shr (a, 1) + shr (b, 1) + ((a | b) & 1);
231}
232
233/* Return 1 if A + B does not overflow. If time_t is unsigned and if
234 B's top bit is set, assume that the sum represents A - -B, and
235 return 1 if the subtraction does not wrap around. */
236static int
237time_t_add_ok (time_t a, time_t b)
238{
239 if (! TYPE_SIGNED (time_t))
240 {
241 time_t sum = a + b;
242 return (sum < a) == (TIME_T_MIDPOINT <= b);
243 }
244 else if (WRAPV)
245 {
246 time_t sum = a + b;
247 return (sum < a) == (b < 0);
248 }
249 else
250 {
251 time_t avg = time_t_avg (a, b);
252 return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
253 }
254}
255
256/* Return 1 if A + B does not overflow. */
257static int
258time_t_int_add_ok (time_t a, int b)
259{
260 verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
261 if (WRAPV)
262 {
263 time_t sum = a + b;
264 return (sum < a) == (b < 0);
265 }
266 else
267 {
268 int a_odd = a & 1;
269 time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
270 return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
271 }
272} 194}
273 195
274/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), 196/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
275 assuming that *T corresponds to *TP and that no clock adjustments 197 assuming that T corresponds to *TP and that no clock adjustments
276 occurred between *TP and the desired time. 198 occurred between *TP and the desired time.
277 If TP is null, return a value not equal to *T; this avoids false matches. 199 Although T and the returned value are of type long_int,
278 If overflow occurs, yield the minimal or maximal value, except do not 200 they represent time_t values and must be in time_t range.
279 yield a value equal to *T. */ 201 If TP is null, return a value not equal to T; this avoids false matches.
280static time_t 202 YEAR and YDAY must not be so large that multiplying them by three times the
203 number of seconds in a year (or day, respectively) would overflow long_int.
204 If the returned value would be out of range, yield the minimal or
205 maximal in-range value, except do not yield a value equal to T. */
206static long_int
281guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, 207guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
282 const time_t *t, const struct tm *tp) 208 long_int t, const struct tm *tp)
283{ 209{
284 if (tp) 210 if (tp)
285 { 211 {
286 time_t d = ydhms_diff (year, yday, hour, min, sec, 212 long_int result;
287 tp->tm_year, tp->tm_yday, 213 long_int d = ydhms_diff (year, yday, hour, min, sec,
288 tp->tm_hour, tp->tm_min, tp->tm_sec); 214 tp->tm_year, tp->tm_yday,
289 if (time_t_add_ok (*t, d)) 215 tp->tm_hour, tp->tm_min, tp->tm_sec);
290 return *t + d; 216 if (! INT_ADD_WRAPV (t, d, &result))
217 return result;
291 } 218 }
292 219
293 /* Overflow occurred one way or another. Return the nearest result 220 /* Overflow occurred one way or another. Return the nearest result
@@ -295,32 +222,51 @@ guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
295 if the actual difference is nonzero, as that would cause a false 222 if the actual difference is nonzero, as that would cause a false
296 match; and don't oscillate between two values, as that would 223 match; and don't oscillate between two values, as that would
297 confuse the spring-forward gap detector. */ 224 confuse the spring-forward gap detector. */
298 return (*t < TIME_T_MIDPOINT 225 return (t < long_int_avg (mktime_min, mktime_max)
299 ? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN) 226 ? (t <= mktime_min + 1 ? t + 1 : mktime_min)
300 : (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX)); 227 : (mktime_max - 1 <= t ? t - 1 : mktime_max));
228}
229
230/* Use CONVERT to convert T to a struct tm value in *TM. T must be in
231 range for time_t. Return TM if successfull, NULL if T is out of
232 range for CONVERT. */
233static struct tm *
234convert_time (struct tm *(*convert) (const time_t *, struct tm *),
235 long_int t, struct tm *tm)
236{
237 time_t x = t;
238 return convert (&x, tm);
301} 239}
302 240
303/* Use CONVERT to convert *T to a broken down time in *TP. 241/* Use CONVERT to convert *T to a broken down time in *TP.
304 If *T is out of range for conversion, adjust it so that 242 If *T is out of range for conversion, adjust it so that
305 it is the nearest in-range value and then convert that. */ 243 it is the nearest in-range value and then convert that.
244 A value is in range if it fits in both time_t and long_int. */
306static struct tm * 245static struct tm *
307ranged_convert (struct tm *(*convert) (const time_t *, struct tm *), 246ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
308 time_t *t, struct tm *tp) 247 long_int *t, struct tm *tp)
309{ 248{
310 struct tm *r = convert (t, tp); 249 struct tm *r;
250 if (*t < mktime_min)
251 *t = mktime_min;
252 else if (mktime_max < *t)
253 *t = mktime_max;
254 r = convert_time (convert, *t, tp);
311 255
312 if (!r && *t) 256 if (!r && *t)
313 { 257 {
314 time_t bad = *t; 258 long_int bad = *t;
315 time_t ok = 0; 259 long_int ok = 0;
316 260
317 /* BAD is a known unconvertible time_t, and OK is a known good one. 261 /* BAD is a known unconvertible value, and OK is a known good one.
318 Use binary search to narrow the range between BAD and OK until 262 Use binary search to narrow the range between BAD and OK until
319 they differ by 1. */ 263 they differ by 1. */
320 while (bad != ok + (bad < 0 ? -1 : 1)) 264 while (true)
321 { 265 {
322 time_t mid = *t = time_t_avg (ok, bad); 266 long_int mid = long_int_avg (ok, bad);
323 r = convert (t, tp); 267 if (mid != ok && mid != bad)
268 break;
269 r = convert_time (convert, mid, tp);
324 if (r) 270 if (r)
325 ok = mid; 271 ok = mid;
326 else 272 else
@@ -331,15 +277,13 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
331 { 277 {
332 /* The last conversion attempt failed; 278 /* The last conversion attempt failed;
333 revert to the most recent successful attempt. */ 279 revert to the most recent successful attempt. */
334 *t = ok; 280 r = convert_time (convert, ok, tp);
335 r = convert (t, tp);
336 } 281 }
337 } 282 }
338 283
339 return r; 284 return r;
340} 285}
341 286
342
343/* Convert *TP to a time_t value, inverting 287/* Convert *TP to a time_t value, inverting
344 the monotonic and mostly-unit-linear conversion function CONVERT. 288 the monotonic and mostly-unit-linear conversion function CONVERT.
345 Use *OFFSET to keep track of a guess at the offset of the result, 289 Use *OFFSET to keep track of a guess at the offset of the result,
@@ -349,9 +293,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
349time_t 293time_t
350__mktime_internal (struct tm *tp, 294__mktime_internal (struct tm *tp,
351 struct tm *(*convert) (const time_t *, struct tm *), 295 struct tm *(*convert) (const time_t *, struct tm *),
352 time_t *offset) 296 mktime_offset_t *offset)
353{ 297{
354 time_t t, gt, t0, t1, t2; 298 long_int t, gt, t0, t1, t2, dt;
355 struct tm tm; 299 struct tm tm;
356 300
357 /* The maximum number of probes (calls to CONVERT) should be enough 301 /* The maximum number of probes (calls to CONVERT) should be enough
@@ -381,9 +325,7 @@ __mktime_internal (struct tm *tp,
381 long_int year = lyear_requested + mon_years; 325 long_int year = lyear_requested + mon_years;
382 326
383 /* The other values need not be in range: 327 /* The other values need not be in range:
384 the remaining code handles minor overflows correctly, 328 the remaining code handles overflows correctly. */
385 assuming int and time_t arithmetic wraps around.
386 Major overflows are caught at the end. */
387 329
388 /* Calculate day of year from year, month, and day of month. 330 /* Calculate day of year from year, month, and day of month.
389 The result need not be in range. */ 331 The result need not be in range. */
@@ -393,7 +335,7 @@ __mktime_internal (struct tm *tp,
393 long_int lmday = mday; 335 long_int lmday = mday;
394 long_int yday = mon_yday + lmday; 336 long_int yday = mon_yday + lmday;
395 337
396 time_t guessed_offset = *offset; 338 int negative_offset_guess;
397 339
398 int sec_requested = sec; 340 int sec_requested = sec;
399 341
@@ -410,71 +352,14 @@ __mktime_internal (struct tm *tp,
410 /* Invert CONVERT by probing. First assume the same offset as last 352 /* Invert CONVERT by probing. First assume the same offset as last
411 time. */ 353 time. */
412 354
355 INT_SUBTRACT_WRAPV (0, *offset, &negative_offset_guess);
413 t0 = ydhms_diff (year, yday, hour, min, sec, 356 t0 = ydhms_diff (year, yday, hour, min, sec,
414 EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset); 357 EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, negative_offset_guess);
415
416 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
417 {
418 /* time_t isn't large enough to rule out overflows, so check
419 for major overflows. A gross check suffices, since if t0
420 has overflowed, it is off by a multiple of TIME_T_MAX -
421 TIME_T_MIN + 1. So ignore any component of the difference
422 that is bounded by a small value. */
423
424 /* Approximate log base 2 of the number of time units per
425 biennium. A biennium is 2 years; use this unit instead of
426 years to avoid integer overflow. For example, 2 average
427 Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
428 which is 63113904 seconds, and rint (log2 (63113904)) is
429 26. */
430 int ALOG2_SECONDS_PER_BIENNIUM = 26;
431 int ALOG2_MINUTES_PER_BIENNIUM = 20;
432 int ALOG2_HOURS_PER_BIENNIUM = 14;
433 int ALOG2_DAYS_PER_BIENNIUM = 10;
434 int LOG2_YEARS_PER_BIENNIUM = 1;
435
436 int approx_requested_biennia =
437 (SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
438 - SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
439 + SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
440 + SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
441 + SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
442 + (LEAP_SECONDS_POSSIBLE
443 ? 0
444 : SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
445
446 int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
447 int diff = approx_biennia - approx_requested_biennia;
448 int approx_abs_diff = diff < 0 ? -1 - diff : diff;
449
450 /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
451 gives a positive value of 715827882. Setting a variable
452 first then doing math on it seems to work.
453 (ghazi@caip.rutgers.edu) */
454 time_t time_t_max = TIME_T_MAX;
455 time_t time_t_min = TIME_T_MIN;
456 time_t overflow_threshold =
457 (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
458
459 if (overflow_threshold < approx_abs_diff)
460 {
461 /* Overflow occurred. Try repairing it; this might work if
462 the time zone offset is enough to undo the overflow. */
463 time_t repaired_t0 = -1 - t0;
464 approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
465 diff = approx_biennia - approx_requested_biennia;
466 approx_abs_diff = diff < 0 ? -1 - diff : diff;
467 if (overflow_threshold < approx_abs_diff)
468 return -1;
469 guessed_offset += repaired_t0 - t0;
470 t0 = repaired_t0;
471 }
472 }
473 358
474 /* Repeatedly use the error to improve the guess. */ 359 /* Repeatedly use the error to improve the guess. */
475 360
476 for (t = t1 = t2 = t0, dst2 = 0; 361 for (t = t1 = t2 = t0, dst2 = 0;
477 (gt = guess_time_tm (year, yday, hour, min, sec, &t, 362 (gt = guess_time_tm (year, yday, hour, min, sec, t,
478 ranged_convert (convert, &t, &tm)), 363 ranged_convert (convert, &t, &tm)),
479 t != gt); 364 t != gt);
480 t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0) 365 t1 = t2, t2 = t, t = gt, dst2 = tm.tm_isdst != 0)
@@ -531,39 +416,42 @@ __mktime_internal (struct tm *tp,
531 416
532 for (delta = stride; delta < delta_bound; delta += stride) 417 for (delta = stride; delta < delta_bound; delta += stride)
533 for (direction = -1; direction <= 1; direction += 2) 418 for (direction = -1; direction <= 1; direction += 2)
534 if (time_t_int_add_ok (t, delta * direction)) 419 {
535 { 420 long_int ot;
536 time_t ot = t + delta * direction; 421 if (! INT_ADD_WRAPV (t, delta * direction, &ot))
537 struct tm otm; 422 {
538 ranged_convert (convert, &ot, &otm); 423 struct tm otm;
539 if (! isdst_differ (isdst, otm.tm_isdst)) 424 ranged_convert (convert, &ot, &otm);
540 { 425 if (! isdst_differ (isdst, otm.tm_isdst))
541 /* We found the desired tm_isdst. 426 {
542 Extrapolate back to the desired time. */ 427 /* We found the desired tm_isdst.
543 t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); 428 Extrapolate back to the desired time. */
544 ranged_convert (convert, &t, &tm); 429 t = guess_time_tm (year, yday, hour, min, sec, ot, &otm);
545 goto offset_found; 430 ranged_convert (convert, &t, &tm);
546 } 431 goto offset_found;
547 } 432 }
433 }
434 }
548 } 435 }
549 436
550 offset_found: 437 offset_found:
551 *offset = guessed_offset + t - t0; 438 /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS.
439 This is just a heuristic to speed up the next mktime call, and
440 correctness is unaffected if integer overflow occurs here. */
441 INT_SUBTRACT_WRAPV (t, t0, &dt);
442 INT_SUBTRACT_WRAPV (dt, negative_offset_guess, offset);
552 443
553 if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec) 444 if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
554 { 445 {
555 /* Adjust time to reflect the tm_sec requested, not the normalized value. 446 /* Adjust time to reflect the tm_sec requested, not the normalized value.
556 Also, repair any damage from a false match due to a leap second. */ 447 Also, repair any damage from a false match due to a leap second. */
557 int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; 448 long_int sec_adjustment = sec == 0 && tm.tm_sec == 60;
558 if (! time_t_int_add_ok (t, sec_requested)) 449 sec_adjustment -= sec;
450 sec_adjustment += sec_requested;
451 if (INT_ADD_WRAPV (t, sec_adjustment, &t)
452 || ! (mktime_min <= t && t <= mktime_max)
453 || ! convert_time (convert, t, &tm))
559 return -1; 454 return -1;
560 t1 = t + sec_requested;
561 if (! time_t_int_add_ok (t1, sec_adjustment))
562 return -1;
563 t2 = t1 + sec_adjustment;
564 if (! convert (&t2, &tm))
565 return -1;
566 t = t2;
567 } 455 }
568 456
569 *tp = tm; 457 *tp = tm;
@@ -571,11 +459,7 @@ __mktime_internal (struct tm *tp,
571} 459}
572 460
573 461
574/* FIXME: This should use a signed type wide enough to hold any UTC 462static mktime_offset_t localtime_offset;
575 offset in seconds. 'int' should be good enough for GNU code. We
576 can't fix this unilaterally though, as other modules invoke
577 __mktime_internal. */
578static time_t localtime_offset;
579 463
580/* Convert *TP to a time_t value. */ 464/* Convert *TP to a time_t value. */
581time_t 465time_t
@@ -600,7 +484,7 @@ libc_hidden_def (mktime)
600libc_hidden_weak (timelocal) 484libc_hidden_weak (timelocal)
601#endif 485#endif
602 486
603#if defined DEBUG_MKTIME && DEBUG_MKTIME 487#if DEBUG_MKTIME
604 488
605static int 489static int
606not_equal_tm (const struct tm *a, const struct tm *b) 490not_equal_tm (const struct tm *a, const struct tm *b)
@@ -652,6 +536,14 @@ main (int argc, char **argv)
652 time_t tk, tl, tl1; 536 time_t tk, tl, tl1;
653 char trailer; 537 char trailer;
654 538
539 /* Sanity check, plus call tzset. */
540 tl = 0;
541 if (! localtime (&tl))
542 {
543 printf ("localtime (0) fails\n");
544 status = 1;
545 }
546
655 if ((argc == 3 || argc == 4) 547 if ((argc == 3 || argc == 4)
656 && (sscanf (argv[1], "%d-%d-%d%c", 548 && (sscanf (argv[1], "%d-%d-%d%c",
657 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) 549 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
@@ -665,12 +557,7 @@ main (int argc, char **argv)
665 tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); 557 tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
666 tmk = tm; 558 tmk = tm;
667 tl = mktime (&tmk); 559 tl = mktime (&tmk);
668 lt = localtime (&tl); 560 lt = localtime_r (&tl, &tml);
669 if (lt)
670 {
671 tml = *lt;
672 lt = &tml;
673 }
674 printf ("mktime returns %ld == ", (long int) tl); 561 printf ("mktime returns %ld == ", (long int) tl);
675 print_tm (&tmk); 562 print_tm (&tmk);
676 printf ("\n"); 563 printf ("\n");
@@ -685,16 +572,16 @@ main (int argc, char **argv)
685 if (argc == 4) 572 if (argc == 4)
686 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) 573 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
687 { 574 {
688 lt = localtime (&tl); 575 lt = localtime_r (&tl, &tml);
689 if (lt) 576 if (lt)
690 { 577 {
691 tmk = tml = *lt; 578 tmk = tml;
692 tk = mktime (&tmk); 579 tk = mktime (&tmk);
693 status |= check_result (tk, tmk, tl, &tml); 580 status |= check_result (tk, tmk, tl, &tml);
694 } 581 }
695 else 582 else
696 { 583 {
697 printf ("localtime (%ld) yields 0\n", (long int) tl); 584 printf ("localtime_r (%ld) yields 0\n", (long int) tl);
698 status = 1; 585 status = 1;
699 } 586 }
700 tl1 = tl + by; 587 tl1 = tl + by;
@@ -705,16 +592,16 @@ main (int argc, char **argv)
705 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1) 592 for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
706 { 593 {
707 /* Null benchmark. */ 594 /* Null benchmark. */
708 lt = localtime (&tl); 595 lt = localtime_r (&tl, &tml);
709 if (lt) 596 if (lt)
710 { 597 {
711 tmk = tml = *lt; 598 tmk = tml;
712 tk = tl; 599 tk = tl;
713 status |= check_result (tk, tmk, tl, &tml); 600 status |= check_result (tk, tmk, tl, &tml);
714 } 601 }
715 else 602 else
716 { 603 {
717 printf ("localtime (%ld) yields 0\n", (long int) tl); 604 printf ("localtime_r (%ld) yields 0\n", (long int) tl);
718 status = 1; 605 status = 1;
719 } 606 }
720 tl1 = tl + by; 607 tl1 = tl + by;