aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2011-01-30 11:22:02 -0800
committerPaul Eggert2011-01-30 11:22:02 -0800
commit3de84ad9c45382c181e3383d433442f4e19ba722 (patch)
tree8abbc5027d45865df833779061ba6471c1a6cc89 /lib
parent09aa1eb8eea75e4f53dfee40e0f46f65751d31bf (diff)
downloademacs-3de84ad9c45382c181e3383d433442f4e19ba722.tar.gz
emacs-3de84ad9c45382c181e3383d433442f4e19ba722.zip
gnulib: import mktime and move-if-change fixes from gnulib
* configure: Regenerate from the following. 2011-01-30 Paul Eggert <eggert@cs.ucla.edu> mktime: clarify long_int width checking * lib/mktime.c (long_int_is_wide_enough): Move this assertion to the top level, to make it clearer that the assumption about long_int width is being checked. See <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00554.html>. 2011-01-29 Paul Eggert <eggert@cs.ucla.edu> TYPE_MAXIMUM: avoid theoretically undefined behavior * lib/intprops.h (TYPE_MINIMUM, TYPE_MAXIMUM): Do not shift a negative number, which the C Standard says has undefined behavior. In practice this is not a problem, but might as well do it by the book. Reported by Rich Felker and Eric Blake; see <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00493.html>. * m4/mktime.m4 (AC_FUNC_MKTIME): Likewise. * lib/mktime.c (TYPE_MAXIMUM): Redo slightly to match the others. mktime: #undef mktime before #defining it * lib/mktime.c (mktime) [DEBUG]: #undef mktime before #defining it. mktime: systematically normalize tm_isdst comparisons * lib/mktime.c (isdst_differ): New function. (__mktime_internal): Use it systematically for all isdst comparisons. This completes the fix for libc BZ #6723, and removes the need for normalizing tm_isdst. See <http://sourceware.org/bugzilla/show_bug.cgi?id=6723> (not_equal_tm) [DEBUG]: Use isdst_differ here, too. mktime: fix some integer overflow issues and sidestep the rest This was prompted by a bug report by Benjamin Lindner for MinGW <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00472.html>. His bug is due to signed integer overflow (0 - INT_MIN), and I I scanned through mktime.c looking for other integer overflow problems, fixing all the bugs I found. Although the C Standard says the resulting code is still not safe in the presence of integer overflow, in practice it should be good enough for all real-world two's-complement implementations, except for debugging environments that deliberately trap on integer overflow (e.g., gcc -ftrapv). * lib/mktime.c (WRAPV): New macro. (SHR): Also check that long_int and time_t shift right in the usual way, before using the fast-but-unportable method. (TYPE_ONES_COMPLEMENT, TYPE_SIGNED_MAGNITUDE): Remove, no longer used. The code already assumed two's complement, so there's no need to test for alternatives. All uses removed. (TYPE_MAXIMUM): Don't rely here on overflow behavior not defined by the C standard. Problem reported by Rich Felker in <http://lists.gnu.org/archive/html/bug-gnulib/2011-01/msg00488.html>. (twos_complement_arithmetic): Also check long_int and time_t. (time_t_avg, time_t_add_ok, time_t_int_add_ok): New functions. (guess_time_tm, ranged_convert, __mktime_internal): Use them. (__mktime_internal): Avoid integer overflow with unary subtraction in two instances where -1 - X is an adequate replacement for -X, since the calculations are approximate. 2011-01-29 Eric Blake <eblake@redhat.com> mktime: avoid infinite loop * m4/mktime.m4 (AC_FUNC_MKTIME): Avoid overflow on possibly-signed type; behavior is still undefined but portable to all known targets. Reported by Rich Felker. 2011-01-28 Paul Eggert <eggert@cs.ucla.edu> mktime: avoid problems on NetBSD 5 / i386 * lib/mktime.c (long_int): New type. This works around a problem on NetBSD 5 / i386, where 'long int' and 'int' are both 32 bits but time_t is 64 bits, and where I expect the existing code is wrong in some cases. (leapyear, ydhms_diff, guess_time_tm, __mktime_internal): Use it. (ydhms_diff): Bring back the compile-time check for wide-enough year and yday. mktime: fix misspelling in comment * lib/mktime.c (__mktime_internal): Fix misspelling in comment. This merges all recent glibc changes of importance. 2011-01-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> move-if-change: cope with concurrent mv of identical file. * move-if-change (CMPPROG): Accept environment variable as an override for `cmp'. (usage): Document CMPPROG. Adjust comparison to drop stdout. Cope with failure of mv if the target file exists and is identical to the source, for parallel builds. Report from H.J. Lu against binutils in PR binutils/12283.
Diffstat (limited to 'lib')
-rw-r--r--lib/intprops.h4
-rw-r--r--lib/mktime.c198
2 files changed, 135 insertions, 67 deletions
diff --git a/lib/intprops.h b/lib/intprops.h
index 511a5aa9890..58b1b3fbf44 100644
--- a/lib/intprops.h
+++ b/lib/intprops.h
@@ -49,11 +49,11 @@
49 ? (t) 0 \ 49 ? (t) 0 \
50 : TYPE_SIGNED_MAGNITUDE (t) \ 50 : TYPE_SIGNED_MAGNITUDE (t) \
51 ? ~ (t) 0 \ 51 ? ~ (t) 0 \
52 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) 52 : ~ TYPE_MAXIMUM (t)))
53# define TYPE_MAXIMUM(t) \ 53# define TYPE_MAXIMUM(t) \
54 ((t) (! TYPE_SIGNED (t) \ 54 ((t) (! TYPE_SIGNED (t) \
55 ? (t) -1 \ 55 ? (t) -1 \
56 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) 56 : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
57 57
58/* Return zero if T can be determined to be an unsigned type. 58/* Return zero if T can be determined to be an unsigned type.
59 Otherwise, return 1. 59 Otherwise, return 1.
diff --git a/lib/mktime.c b/lib/mktime.c
index f77330564fc..c68ad9ba262 100644
--- a/lib/mktime.c
+++ b/lib/mktime.c
@@ -25,6 +25,24 @@
25# include <config.h> 25# include <config.h>
26#endif 26#endif
27 27
28/* Some of the code in this file assumes that signed integer overflow
29 silently wraps around. This assumption can't easily be programmed
30 around, nor can it be checked for portably at compile-time or
31 easily eliminated at run-time.
32
33 Define WRAPV to 1 if the assumption is valid. Otherwise, define it
34 to 0; this forces the use of slower code that, while not guaranteed
35 by the C Standard, works on all production platforms that we know
36 about. */
37#ifndef WRAPV
38# if (__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__
39# pragma GCC optimize ("wrapv")
40# define WRAPV 1
41# else
42# define WRAPV 0
43# endif
44#endif
45
28/* Assume that leap seconds are possible, unless told otherwise. 46/* Assume that leap seconds are possible, unless told otherwise.
29 If the host has a `zic' command with a `-L leapsecondfilename' option, 47 If the host has a `zic' command with a `-L leapsecondfilename' option,
30 then it supports leap seconds; otherwise it probably doesn't. */ 48 then it supports leap seconds; otherwise it probably doesn't. */
@@ -42,9 +60,21 @@
42# include <stdio.h> 60# include <stdio.h>
43# include <stdlib.h> 61# include <stdlib.h>
44/* Make it work even if the system's libc has its own mktime routine. */ 62/* Make it work even if the system's libc has its own mktime routine. */
63# undef mktime
45# define mktime my_mktime 64# define mktime my_mktime
46#endif /* DEBUG */ 65#endif /* DEBUG */
47 66
67/* Verify a requirement at compile-time (unlike assert, which is runtime). */
68#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
69
70/* A signed type that is at least one bit wider than int. */
71#if INT_MAX <= LONG_MAX / 2
72typedef long int long_int;
73#else
74typedef long long int long_int;
75#endif
76verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2);
77
48/* Shift A right by B bits portably, by dividing A by 2**B and 78/* Shift A right by B bits portably, by dividing A by 2**B and
49 truncating towards minus infinity. A and B should be free of side 79 truncating towards minus infinity. A and B should be free of side
50 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where 80 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
@@ -55,9 +85,11 @@
55 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift 85 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
56 right in the usual way when A < 0, so SHR falls back on division if 86 right in the usual way when A < 0, so SHR falls back on division if
57 ordinary A >> B doesn't seem to be the usual signed shift. */ 87 ordinary A >> B doesn't seem to be the usual signed shift. */
58#define SHR(a, b) \ 88#define SHR(a, b) \
59 (-1 >> 1 == -1 \ 89 ((-1 >> 1 == -1 \
60 ? (a) >> (b) \ 90 && (long_int) -1 >> 1 == -1 \
91 && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \
92 ? (a) >> (b) \
61 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) 93 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
62 94
63/* The extra casts in the following macros work around compiler bugs, 95/* The extra casts in the following macros work around compiler bugs,
@@ -68,12 +100,8 @@
68#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) 100#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
69 101
70/* True if negative values of the signed integer type T use two's 102/* True if negative values of the signed integer type T use two's
71 complement, ones' complement, or signed magnitude representation, 103 complement, or if T is an unsigned integer type. */
72 respectively. Much GNU code assumes two's complement, but some
73 people like to be portable to all possible C hosts. */
74#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) 104#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
75#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
76#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
77 105
78/* True if the arithmetic type T is signed. */ 106/* True if the arithmetic type T is signed. */
79#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) 107#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
@@ -85,13 +113,11 @@
85#define TYPE_MINIMUM(t) \ 113#define TYPE_MINIMUM(t) \
86 ((t) (! TYPE_SIGNED (t) \ 114 ((t) (! TYPE_SIGNED (t) \
87 ? (t) 0 \ 115 ? (t) 0 \
88 : TYPE_SIGNED_MAGNITUDE (t) \ 116 : ~ TYPE_MAXIMUM (t)))
89 ? ~ (t) 0 \
90 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
91#define TYPE_MAXIMUM(t) \ 117#define TYPE_MAXIMUM(t) \
92 ((t) (! TYPE_SIGNED (t) \ 118 ((t) (! TYPE_SIGNED (t) \
93 ? (t) -1 \ 119 ? (t) -1 \
94 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) 120 : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
95 121
96#ifndef TIME_T_MIN 122#ifndef TIME_T_MIN
97# define TIME_T_MIN TYPE_MINIMUM (time_t) 123# define TIME_T_MIN TYPE_MINIMUM (time_t)
@@ -101,14 +127,11 @@
101#endif 127#endif
102#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) 128#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
103 129
104/* Verify a requirement at compile-time (unlike assert, which is runtime). */
105#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
106
107verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); 130verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
108verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int)); 131verify (twos_complement_arithmetic,
109/* The code also assumes that signed integer overflow silently wraps 132 (TYPE_TWOS_COMPLEMENT (int)
110 around, but this assumption can't be stated without causing a 133 && TYPE_TWOS_COMPLEMENT (long_int)
111 diagnostic on some hosts. */ 134 && TYPE_TWOS_COMPLEMENT (time_t)));
112 135
113#define EPOCH_YEAR 1970 136#define EPOCH_YEAR 1970
114#define TM_YEAR_BASE 1900 137#define TM_YEAR_BASE 1900
@@ -116,7 +139,7 @@ verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
116 139
117/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ 140/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
118static inline int 141static inline int
119leapyear (long int year) 142leapyear (long_int year)
120{ 143{
121 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. 144 /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
122 Also, work even if YEAR is negative. */ 145 Also, work even if YEAR is negative. */
@@ -150,6 +173,14 @@ const unsigned short int __mon_yday[2][13] =
150# include "mktime-internal.h" 173# include "mktime-internal.h"
151#endif 174#endif
152 175
176/* Return 1 if the values A and B differ according to the rules for
177 tm_isdst: A and B differ if one is zero and the other positive. */
178static int
179isdst_differ (int a, int b)
180{
181 return (!a != !b) & (0 <= a) & (0 <= b);
182}
183
153/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - 184/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
154 (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks 185 (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
155 were not adjusted between the time stamps. 186 were not adjusted between the time stamps.
@@ -162,15 +193,10 @@ const unsigned short int __mon_yday[2][13] =
162 detect overflow. */ 193 detect overflow. */
163 194
164static inline time_t 195static inline time_t
165ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, 196ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
166 int year0, int yday0, int hour0, int min0, int sec0) 197 int year0, int yday0, int hour0, int min0, int sec0)
167{ 198{
168 verify (C99_integer_division, -1 / 2 == 0); 199 verify (C99_integer_division, -1 / 2 == 0);
169#if 0 /* This assertion fails on 32-bit systems with 64-bit time_t, such as
170 NetBSD 5 on i386. */
171 verify (long_int_year_and_yday_are_wide_enough,
172 INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
173#endif
174 200
175 /* Compute intervening leap days correctly even if year is negative. 201 /* Compute intervening leap days correctly even if year is negative.
176 Take care to avoid integer overflow here. */ 202 Take care to avoid integer overflow here. */
@@ -193,6 +219,53 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
193 return seconds; 219 return seconds;
194} 220}
195 221
222/* Return the average of A and B, even if A + B would overflow. */
223static time_t
224time_t_avg (time_t a, time_t b)
225{
226 return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
227}
228
229/* Return 1 if A + B does not overflow. If time_t is unsigned and if
230 B's top bit is set, assume that the sum represents A - -B, and
231 return 1 if the subtraction does not wrap around. */
232static int
233time_t_add_ok (time_t a, time_t b)
234{
235 if (! TYPE_SIGNED (time_t))
236 {
237 time_t sum = a + b;
238 return (sum < a) == (TIME_T_MIDPOINT <= b);
239 }
240 else if (WRAPV)
241 {
242 time_t sum = a + b;
243 return (sum < a) == (b < 0);
244 }
245 else
246 {
247 time_t avg = time_t_avg (a, b);
248 return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
249 }
250}
251
252/* Return 1 if A + B does not overflow. */
253static int
254time_t_int_add_ok (time_t a, int b)
255{
256 verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
257 if (WRAPV)
258 {
259 time_t sum = a + b;
260 return (sum < a) == (b < 0);
261 }
262 else
263 {
264 int a_odd = a & 1;
265 time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
266 return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
267 }
268}
196 269
197/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), 270/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
198 assuming that *T corresponds to *TP and that no clock adjustments 271 assuming that *T corresponds to *TP and that no clock adjustments
@@ -201,7 +274,7 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
201 If overflow occurs, yield the minimal or maximal value, except do not 274 If overflow occurs, yield the minimal or maximal value, except do not
202 yield a value equal to *T. */ 275 yield a value equal to *T. */
203static time_t 276static time_t
204guess_time_tm (long int year, long int yday, int hour, int min, int sec, 277guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
205 const time_t *t, const struct tm *tp) 278 const time_t *t, const struct tm *tp)
206{ 279{
207 if (tp) 280 if (tp)
@@ -209,9 +282,8 @@ guess_time_tm (long int year, long int yday, int hour, int min, int sec,
209 time_t d = ydhms_diff (year, yday, hour, min, sec, 282 time_t d = ydhms_diff (year, yday, hour, min, sec,
210 tp->tm_year, tp->tm_yday, 283 tp->tm_year, tp->tm_yday,
211 tp->tm_hour, tp->tm_min, tp->tm_sec); 284 tp->tm_hour, tp->tm_min, tp->tm_sec);
212 time_t t1 = *t + d; 285 if (time_t_add_ok (*t, d))
213 if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d)) 286 return *t + d;
214 return t1;
215 } 287 }
216 288
217 /* Overflow occurred one way or another. Return the nearest result 289 /* Overflow occurred one way or another. Return the nearest result
@@ -243,9 +315,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
243 they differ by 1. */ 315 they differ by 1. */
244 while (bad != ok + (bad < 0 ? -1 : 1)) 316 while (bad != ok + (bad < 0 ? -1 : 1))
245 { 317 {
246 time_t mid = *t = (bad < 0 318 time_t mid = *t = time_t_avg (ok, bad);
247 ? bad + ((ok - bad) >> 1)
248 : ok + ((bad - ok) >> 1));
249 r = convert (t, tp); 319 r = convert (t, tp);
250 if (r) 320 if (r)
251 ok = mid; 321 ok = mid;
@@ -294,9 +364,7 @@ __mktime_internal (struct tm *tp,
294 int mday = tp->tm_mday; 364 int mday = tp->tm_mday;
295 int mon = tp->tm_mon; 365 int mon = tp->tm_mon;
296 int year_requested = tp->tm_year; 366 int year_requested = tp->tm_year;
297 /* Normalize the value. */ 367 int isdst = tp->tm_isdst;
298 int isdst = ((tp->tm_isdst >> (8 * sizeof (tp->tm_isdst) - 1))
299 | (tp->tm_isdst != 0));
300 368
301 /* 1 if the previous probe was DST. */ 369 /* 1 if the previous probe was DST. */
302 int dst2; 370 int dst2;
@@ -305,8 +373,8 @@ __mktime_internal (struct tm *tp,
305 int mon_remainder = mon % 12; 373 int mon_remainder = mon % 12;
306 int negative_mon_remainder = mon_remainder < 0; 374 int negative_mon_remainder = mon_remainder < 0;
307 int mon_years = mon / 12 - negative_mon_remainder; 375 int mon_years = mon / 12 - negative_mon_remainder;
308 long int lyear_requested = year_requested; 376 long_int lyear_requested = year_requested;
309 long int year = lyear_requested + mon_years; 377 long_int year = lyear_requested + mon_years;
310 378
311 /* The other values need not be in range: 379 /* The other values need not be in range:
312 the remaining code handles minor overflows correctly, 380 the remaining code handles minor overflows correctly,
@@ -318,8 +386,8 @@ __mktime_internal (struct tm *tp,
318 int mon_yday = ((__mon_yday[leapyear (year)] 386 int mon_yday = ((__mon_yday[leapyear (year)]
319 [mon_remainder + 12 * negative_mon_remainder]) 387 [mon_remainder + 12 * negative_mon_remainder])
320 - 1); 388 - 1);
321 long int lmday = mday; 389 long_int lmday = mday;
322 long int yday = mon_yday + lmday; 390 long_int yday = mon_yday + lmday;
323 391
324 time_t guessed_offset = *offset; 392 time_t guessed_offset = *offset;
325 393
@@ -373,9 +441,9 @@ __mktime_internal (struct tm *tp,
373 441
374 int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); 442 int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
375 int diff = approx_biennia - approx_requested_biennia; 443 int diff = approx_biennia - approx_requested_biennia;
376 int abs_diff = diff < 0 ? - diff : diff; 444 int abs_diff = diff < 0 ? -1 - diff : diff;
377 445
378 /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously 446 /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
379 gives a positive value of 715827882. Setting a variable 447 gives a positive value of 715827882. Setting a variable
380 first then doing math on it seems to work. 448 first then doing math on it seems to work.
381 (ghazi@caip.rutgers.edu) */ 449 (ghazi@caip.rutgers.edu) */
@@ -391,7 +459,7 @@ __mktime_internal (struct tm *tp,
391 time_t repaired_t0 = -1 - t0; 459 time_t repaired_t0 = -1 - t0;
392 approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); 460 approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
393 diff = approx_biennia - approx_requested_biennia; 461 diff = approx_biennia - approx_requested_biennia;
394 abs_diff = diff < 0 ? - diff : diff; 462 abs_diff = diff < 0 ? -1 - diff : diff;
395 if (overflow_threshold < abs_diff) 463 if (overflow_threshold < abs_diff)
396 return -1; 464 return -1;
397 guessed_offset += repaired_t0 - t0; 465 guessed_offset += repaired_t0 - t0;
@@ -426,7 +494,7 @@ __mktime_internal (struct tm *tp,
426 494
427 /* We have a match. Check whether tm.tm_isdst has the requested 495 /* We have a match. Check whether tm.tm_isdst has the requested
428 value, if any. */ 496 value, if any. */
429 if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst) 497 if (isdst_differ (isdst, tm.tm_isdst))
430 { 498 {
431 /* tm.tm_isdst has the wrong value. Look for a neighboring 499 /* tm.tm_isdst has the wrong value. Look for a neighboring
432 time with the right value, and use its UTC offset. 500 time with the right value, and use its UTC offset.
@@ -459,22 +527,20 @@ __mktime_internal (struct tm *tp,
459 527
460 for (delta = stride; delta < delta_bound; delta += stride) 528 for (delta = stride; delta < delta_bound; delta += stride)
461 for (direction = -1; direction <= 1; direction += 2) 529 for (direction = -1; direction <= 1; direction += 2)
462 { 530 if (time_t_int_add_ok (t, delta * direction))
463 time_t ot = t + delta * direction; 531 {
464 if ((ot < t) == (direction < 0)) 532 time_t ot = t + delta * direction;
465 { 533 struct tm otm;
466 struct tm otm; 534 ranged_convert (convert, &ot, &otm);
467 ranged_convert (convert, &ot, &otm); 535 if (! isdst_differ (isdst, otm.tm_isdst))
468 if (otm.tm_isdst == isdst) 536 {
469 { 537 /* We found the desired tm_isdst.
470 /* We found the desired tm_isdst. 538 Extrapolate back to the desired time. */
471 Extrapolate back to the desired time. */ 539 t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
472 t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); 540 ranged_convert (convert, &t, &tm);
473 ranged_convert (convert, &t, &tm); 541 goto offset_found;
474 goto offset_found; 542 }
475 } 543 }
476 }
477 }
478 } 544 }
479 545
480 offset_found: 546 offset_found:
@@ -485,11 +551,13 @@ __mktime_internal (struct tm *tp,
485 /* Adjust time to reflect the tm_sec requested, not the normalized value. 551 /* Adjust time to reflect the tm_sec requested, not the normalized value.
486 Also, repair any damage from a false match due to a leap second. */ 552 Also, repair any damage from a false match due to a leap second. */
487 int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; 553 int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
554 if (! time_t_int_add_ok (t, sec_requested))
555 return -1;
488 t1 = t + sec_requested; 556 t1 = t + sec_requested;
557 if (! time_t_int_add_ok (t1, sec_adjustment))
558 return -1;
489 t2 = t1 + sec_adjustment; 559 t2 = t1 + sec_adjustment;
490 if (((t1 < t) != (sec_requested < 0)) 560 if (! convert (&t2, &tm))
491 | ((t2 < t1) != (sec_adjustment < 0))
492 | ! convert (&t2, &tm))
493 return -1; 561 return -1;
494 t = t2; 562 t = t2;
495 } 563 }
@@ -540,7 +608,7 @@ not_equal_tm (const struct tm *a, const struct tm *b)
540 | (a->tm_mon ^ b->tm_mon) 608 | (a->tm_mon ^ b->tm_mon)
541 | (a->tm_year ^ b->tm_year) 609 | (a->tm_year ^ b->tm_year)
542 | (a->tm_yday ^ b->tm_yday) 610 | (a->tm_yday ^ b->tm_yday)
543 | (a->tm_isdst ^ b->tm_isdst)); 611 | isdst_differ (a->tm_isdst, b->tm_isdst));
544} 612}
545 613
546static void 614static void
@@ -664,6 +732,6 @@ main (int argc, char **argv)
664 732
665/* 733/*
666Local Variables: 734Local Variables:
667compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime" 735compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime"
668End: 736End:
669*/ 737*/