From patchwork Sun Sep 9 16:06:24 2018
ContentType: text/plain; charset="utf8"
MIMEVersion: 1.0
ContentTransferEncoding: 8bit
XPatchworkSubmitter: Paul Eggert
XPatchworkId: 29281
Received: (qmail 23779 invoked by alias); 9 Sep 2018 16:06:50 0000
MailingList: contact libcalphahelp@sourceware.org; run by ezmlm
Precedence: bulk
ListId:
ListUnsubscribe:
ListSubscribe:
ListArchive:
ListPost:
ListHelp: ,
Sender: libcalphaowner@sourceware.org
DeliveredTo: mailing list libcalpha@sourceware.org
Received: (qmail 23762 invoked by uid 89); 9 Sep 2018 16:06:50 0000
AuthenticationResults: sourceware.org; auth=none
XSpamSWAREStatus: No, score=24.7 required=5.0 tests=AWL, BAYES_00,
GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT,
SPF_PASS autolearn=ham version=3.3.2 spammy=singapore,
Singapore, occur, practical
XHELO: zimbra.cs.ucla.edu
From: Paul Eggert
To: libcalpha@sourceware.org
Cc: Paul Eggert
Subject: [PATCH 1/2] Merge mktime, timegm from upstream Gnulib
Date: Sun, 9 Sep 2018 09:06:24 0700
MessageId: <20180909160625.152141eggert@cs.ucla.edu>
MIMEVersion: 1.0
[BZ #23603][BZ #16346]
This fixes some obscure problems with integer overflow.
Although it looks scary, it is almost all a byteforbyte copy
from Gnulib, and the Gnulib code has been tested reasonably well.
* include/intprops.h: New file, copied from Gnulib.
* include/verify.h, time/mktimeinternal.h:
New tiny files, simplified from Gnulib.
* time/mktime.c: Copy from Gnulib. This has the following changes:
Do not include config.h if DEBUG_MKTIME is nonzero.
Include stdbool.h, intprops.h, verify.h.
Include string.h only if needed.
Include stdlib.h on MSWindows.
Include mktimeinternal.h.
(DEBUG_MKTIME): Default to 0, and simplify later uses.
(NEED_MKTIME_INTERNAL, NEED_MKTIME_WINDOWS)
(NEED_MKTIME_WORKING): Give default values to pacify Wundef,
which glibc uses. Default NEED_MKTIME_WORKING to DEBUG_MKTIME, to
simplify later conditionals; default the others to zero. Use
these conditionals to express only the code needed on the current
platform. In uses of these conditionals, explicitly spell out how
_LIBC affects things, so it’s easier to review from a glibc
viewpoint.
(WRAPV): Remove; no longer needed now that we have
systematic overflow checking.
(my_tzset, __tzset) [!_LIBC]: New function and macro, to better
compartmentalize tzset issues. Move systemdependent tzsettish
code here from mktime.
(verify): Remove; now done by verify.h. All uses changed.
(long_int): Use a moreconservative definition, to avoid
integer overflow.
(SHR): Remove, replacing with ...
(shr): New function, which means we needn’t worry about side
effects in args, and conversion analysis is simpler.
(TYPE_IS_INTEGER, TYPE_TWOS_COMPLEMENT, TYPE_SIGNED, TYPE_MINIMUM)
(TYPE_MAXIMUM, TIME_T_MIN, TIME_T_MAX, TIME_T_MIDPOINT)
(time_t_avg, time_t_add_ok): Remove.
(mktime_min, mktime_max): New constants.
(leapyear, isdst_differ): Use bool for booleans.
(ydhms_diff, guess_time_tm, ranged_convert, __mktime_internal):
Use long_int, not time_t, for mktime differences.
(long_int_avg): New function, replacing time_t_avg.
INT_ADD_WRAPV replaces time_t_add_ok.
(guess_time_tm): 6th arg is now long_int, not time_t const *.
All uses changed.
(convert_time): New function.
(ranged_convert): Use it.
(__mktime_internal): Last arg now points to mktime_offset_t, not
time_t. All uses changed. This is a noop on glibc, where
mktime_offset_t is always time_t. Use int, not time_t, for UTC
offset guess. Directly check for integer overflow instead of
using a heuristic that works only 99.9...% of the time.
Access *OFFSET only once, to avoid an unlikely race if the
compiler delays a load and if this cascades into a signed integer
overflow.
(mktime): Move tzsettish code to my_tzset, and move
localtime_offset to within mktime so that it doesn’t
need a separate ifdef.
(main) [DEBUG_MKTIME]: Speed up by using localtime_r
instead of localtime.
* time/timegm.c: Copy from Gnulib. This has the following changes:
Include mktimeinternal.h.
[!_LIBC]: Include config.h and time.h. Do not include
timegm.h or time_r.h. Make __mktime_internal a macro,
and include mktimeinternal.h to get its declaration.
(timegm): Temporary is now mktime_offset_t, not time_t.
This affects only Gnulib.

ChangeLog  70 ++++++
include/intprops.h  455 ++++++++++++++++++++++++++++++++++
include/verify.h  2 +
time/mktimeinternal.h  1 +
time/mktime.c  545 +++++++++++++++++++
time/timegm.c  23 +
6 files changed, 780 insertions(+), 316 deletions()
create mode 100644 include/intprops.h
create mode 100644 include/verify.h
create mode 100644 time/mktimeinternal.h
diff git a/ChangeLog b/ChangeLog
index 611caf9bd8..68f6728290 100644
 a/ChangeLog
+++ b/ChangeLog
@@ 1,3 +1,73 @@
+20180909 Paul Eggert
+
+ Merge mktime, timegm from upstream Gnulib
+ [BZ #23603][BZ #16346]
+ This fixes some obscure problems with integer overflow.
+ Although it looks scary, it is almost all a byteforbyte copy
+ from Gnulib, and the Gnulib code has been tested reasonably well.
+ * include/intprops.h: New file, copied from Gnulib.
+ * include/verify.h, time/mktimeinternal.h:
+ New tiny files, simplified from Gnulib.
+ * time/mktime.c: Copy from Gnulib. This has the following changes:
+ Do not include config.h if DEBUG_MKTIME is nonzero.
+ Include stdbool.h, intprops.h, verify.h.
+ Include string.h only if needed.
+ Include stdlib.h on MSWindows.
+ Include mktimeinternal.h.
+ (DEBUG_MKTIME): Default to 0, and simplify later uses.
+ (NEED_MKTIME_INTERNAL, NEED_MKTIME_WINDOWS)
+ (NEED_MKTIME_WORKING): Give default values to pacify Wundef,
+ which glibc uses. Default NEED_MKTIME_WORKING to DEBUG_MKTIME, to
+ simplify later conditionals; default the others to zero. Use
+ these conditionals to express only the code needed on the current
+ platform. In uses of these conditionals, explicitly spell out how
+ _LIBC affects things, so itâ€™s easier to review from a glibc
+ viewpoint.
+ (WRAPV): Remove; no longer needed now that we have
+ systematic overflow checking.
+ (my_tzset, __tzset) [!_LIBC]: New function and macro, to better
+ compartmentalize tzset issues. Move systemdependent tzsettish
+ code here from mktime.
+ (verify): Remove; now done by verify.h. All uses changed.
+ (long_int): Use a moreconservative definition, to avoid
+ integer overflow.
+ (SHR): Remove, replacing with ...
+ (shr): New function, which means we neednâ€™t worry about side
+ effects in args, and conversion analysis is simpler.
+ (TYPE_IS_INTEGER, TYPE_TWOS_COMPLEMENT, TYPE_SIGNED, TYPE_MINIMUM)
+ (TYPE_MAXIMUM, TIME_T_MIN, TIME_T_MAX, TIME_T_MIDPOINT)
+ (time_t_avg, time_t_add_ok): Remove.
+ (mktime_min, mktime_max): New constants.
+ (leapyear, isdst_differ): Use bool for booleans.
+ (ydhms_diff, guess_time_tm, ranged_convert, __mktime_internal):
+ Use long_int, not time_t, for mktime differences.
+ (long_int_avg): New function, replacing time_t_avg.
+ INT_ADD_WRAPV replaces time_t_add_ok.
+ (guess_time_tm): 6th arg is now long_int, not time_t const *.
+ All uses changed.
+ (convert_time): New function.
+ (ranged_convert): Use it.
+ (__mktime_internal): Last arg now points to mktime_offset_t, not
+ time_t. All uses changed. This is a noop on glibc, where
+ mktime_offset_t is always time_t. Use int, not time_t, for UTC
+ offset guess. Directly check for integer overflow instead of
+ using a heuristic that works only 99.9...% of the time.
+ Access *OFFSET only once, to avoid an unlikely race if the
+ compiler delays a load and if this cascades into a signed integer
+ overflow.
+ (mktime): Move tzsettish code to my_tzset, and move
+ localtime_offset to within mktime so that it doesnâ€™t
+ need a separate ifdef.
+ (main) [DEBUG_MKTIME]: Speed up by using localtime_r
+ instead of localtime.
+ * time/timegm.c: Copy from Gnulib. This has the following changes:
+ Include mktimeinternal.h.
+ [!_LIBC]: Include config.h and time.h. Do not include
+ timegm.h or time_r.h. Make __mktime_internal a macro,
+ and include mktimeinternal.h to get its declaration.
+ (timegm): Temporary is now mktime_offset_t, not time_t.
+ This affects only Gnulib.
+
20180906 Stefan Liebler
* sysdeps/s390/fpu/libmtestulps: Regenerated.
diff git a/include/intprops.h b/include/intprops.h
new file mode 100644
index 0000000000..9702aec4c6
 /dev/null
+++ b/include/intprops.h
@@ 0,0 +1,455 @@
+/* intprops.h  properties of integer types
+
+ Copyright (C) 20012018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see . */
+
+/* Written by Paul Eggert. */
+
+#ifndef _GL_INTPROPS_H
+#define _GL_INTPROPS_H
+
+#include
+
+/* Return a value with the common real type of E and V and the value of V.
+ Do not evaluate E. */
+#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
+
+/* Act like _GL_INT_CONVERT (E, V) but work around a bug in IRIX 6.5 cc; see
+ . */
+#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e))  (v))
+
+/* 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 the real type T is signed. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) 1))
+
+/* Return 1 if the real expression E, after promotion, has a
+ signed or floating type. Do not evaluate E. */
+#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
+
+
+/* Minimum and maximum values for integer types and expressions. */
+
+/* The width in bits of the integer type or expression T.
+ Do not evaluate T.
+ Padding bits are not supported; this is checked at compiletime below. */
+#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
+
+/* The maximum and minimum values for the integer type T. */
+#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
+#define TYPE_MAXIMUM(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) 1 \
+ : ((((t) 1 << (TYPE_WIDTH (t)  2))  1) * 2 + 1)))
+
+/* The maximum and minimum values for the type of the expression E,
+ after integer promotion. E is not evaluated. */
+#define _GL_INT_MINIMUM(e) \
+ (EXPR_SIGNED (e) \
+ ? ~ _GL_SIGNED_INT_MAXIMUM (e) \
+ : _GL_INT_CONVERT (e, 0))
+#define _GL_INT_MAXIMUM(e) \
+ (EXPR_SIGNED (e) \
+ ? _GL_SIGNED_INT_MAXIMUM (e) \
+ : _GL_INT_NEGATE_CONVERT (e, 1))
+#define _GL_SIGNED_INT_MAXIMUM(e) \
+ (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0)  2))  1) * 2 + 1)
+
+/* Work around OpenVMS incompatibility with C99. */
+#if !defined LLONG_MAX && defined __INT64_MAX
+# define LLONG_MAX __INT64_MAX
+# define LLONG_MIN __INT64_MIN
+#endif
+
+/* This include file assumes that signed types are two's complement without
+ padding bits; the above macros have undefined behavior otherwise.
+ If this is a problem for you, please let us know how to fix it for your host.
+ This assumption is tested by the intpropstests module. */
+
+/* Does the __typeof__ keyword work? This could be done by
+ 'configure', but for now it's easier to do it by hand. */
+#if (2 <= __GNUC__ \
+  (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
+  (0x5110 <= __SUNPRO_C && !__STDC__))
+# define _GL_HAVE___TYPEOF__ 1
+#else
+# define _GL_HAVE___TYPEOF__ 0
+#endif
+
+/* Return 1 if the integer type or expression T might be signed. Return 0
+ if it is definitely unsigned. This macro does not evaluate its argument,
+ and expands to an integer constant expression. */
+#if _GL_HAVE___TYPEOF__
+# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
+#else
+# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
+#endif
+
+/* Bound on length of the string representing an unsigned integer
+ value representable in B bits. log10 (2.0) < 146/485. The
+ smallest value of B where this bound is not tight is 2621. */
+#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
+
+/* Bound on length of the string representing an integer type or expression T.
+ Subtract 1 for the sign bit if T is signed, and then add 1 more for
+ a minus sign if needed.
+
+ Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is
+ signed, this macro may overestimate the true bound by one byte when
+ applied to unsigned types of size 2, 4, 16, ... bytes. */
+#define INT_STRLEN_BOUND(t) \
+ (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t)  _GL_SIGNED_TYPE_OR_EXPR (t)) \
+ + _GL_SIGNED_TYPE_OR_EXPR (t))
+
+/* Bound on buffer size needed to represent an integer type or expression T,
+ including the terminating null. */
+#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
+
+
+/* Range overflow checks.
+
+ The INT__RANGE_OVERFLOW macros return 1 if the corresponding C
+ operators might not yield numerically correct answers due to
+ arithmetic overflow. They do not rely on undefined or
+ implementationdefined behavior. Their implementations are simple
+ and straightforward, but they are a bit harder to use than the
+ INT__OVERFLOW macros described below.
+
+ Example usage:
+
+ long int i = ...;
+ long int j = ...;
+ if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX))
+ printf ("multiply would overflow");
+ else
+ printf ("product is %ld", i * j);
+
+ Restrictions on *_RANGE_OVERFLOW macros:
+
+ These macros do not check for all possible numerical problems or
+ undefined or unspecified behavior: they do not check for division
+ by zero, for bad shift counts, or for shifting negative numbers.
+
+ These macros may evaluate their arguments zero or multiple times,
+ so the arguments should not have side effects. The arithmetic
+ arguments (including the MIN and MAX arguments) must be of the same
+ integer type after the usual arithmetic conversions, and the type
+ must have minimum value MIN and maximum MAX. Unsigned types should
+ use a zero MIN of the proper type.
+
+ These macros are tuned for constant MIN and MAX. For commutative
+ operations such as A + B, they are also tuned for constant B. */
+
+/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? (a) < (min)  (b) \
+ : (max)  (b) < (a))
+
+/* Return 1 if A  B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? (max) + (b) < (a) \
+ : (a) < (min) + (b))
+
+/* Return 1 if  A would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. */
+#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \
+ ((min) < 0 \
+ ? (a) <  (max) \
+ : 0 < (a))
+
+/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Avoid && and  as they tickle
+ bugs in Sun C 5.11 2010/08/13 and other compilers; see
+ . */
+#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \
+ ((b) < 0 \
+ ? ((a) < 0 \
+ ? (a) < (max) / (b) \
+ : (b) == 1 \
+ ? 0 \
+ : (min) / (b) < (a)) \
+ : (b) == 0 \
+ ? 0 \
+ : ((a) < 0 \
+ ? (a) < (min) / (b) \
+ : (max) / (b) < (a)))
+
+/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Do not check for division by zero. */
+#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \
+ ((min) < 0 && (b) == 1 && (a) <  (max))
+
+/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Do not check for division by zero.
+ Mathematically, % should never overflow, but on x86like hosts
+ INT_MIN % 1 traps, and the C standard permits this, so treat this
+ as an overflow too. */
+#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \
+ INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)
+
+/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic.
+ See above for restrictions. Here, MIN and MAX are for A only, and B need
+ not be of the same type as the other arguments. The C standard says that
+ behavior is undefined for shifts unless 0 <= B < wordwidth, and that when
+ A is negative then A << B has undefined behavior and A >> B has
+ implementationdefined behavior, but do not check these other
+ restrictions. */
+#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \
+ ((a) < 0 \
+ ? (a) < (min) >> (b) \
+ : (max) >> (b) < (a))
+
+/* True if __builtin_add_overflow (A, B, P) works when P is nonnull. */
+#if 5 <= __GNUC__ && !defined __ICC
+# define _GL_HAS_BUILTIN_OVERFLOW 1
+#else
+# define _GL_HAS_BUILTIN_OVERFLOW 0
+#endif
+
+/* True if __builtin_add_overflow_p (A, B, C) works. */
+#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
+
+/* The _GL*_OVERFLOW macros have the same restrictions as the
+ *_RANGE_OVERFLOW macros, except that they do not assume that operands
+ (e.g., A and B) have the same type as MIN and MAX. Instead, they assume
+ that the result (e.g., A + B) has that type. */
+#if _GL_HAS_BUILTIN_OVERFLOW_P
+# define _GL_ADD_OVERFLOW(a, b, min, max) \
+ __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
+# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \
+ __builtin_sub_overflow_p (a, b, (__typeof__ ((a)  (b))) 0)
+# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \
+ __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0)
+#else
+# define _GL_ADD_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \
+ : (a) < 0 ? (b) <= (a) + (b) \
+ : (b) < 0 ? (a) <= (a) + (b) \
+ : (a) + (b) < (b))
+# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \
+ : (a) < 0 ? 1 \
+ : (b) < 0 ? (a)  (b) <= (a) \
+ : (a) < (b))
+# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \
+ (((min) == 0 && (((a) < 0 && 0 < (b))  ((b) < 0 && 0 < (a)))) \
+  INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))
+#endif
+#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) <  (max) \
+ : (a) < 0 ? (b) <= (a) + (b)  1 \
+ : (b) < 0 && (a) + (b) <= (a))
+#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \
+ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) <  (max) \
+ : (a) < 0 ? (a) % (b) != ((max)  (b) + 1) % (b) \
+ : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max))
+
+/* Return a nonzero value if A is a mathematical multiple of B, where
+ A is unsigned, B is negative, and MAX is the maximum value of A's
+ type. A's type must be the same as (A % B)'s type. Normally (A %
+ B == 0) suffices, but things get tricky if B would overflow. */
+#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \
+ (((b) < _GL_SIGNED_INT_MAXIMUM (b) \
+ ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \
+ ? (a) \
+ : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \
+ : (a) %  (b)) \
+ == 0)
+
+/* Check for integer overflow, and report low order bits of answer.
+
+ The INT__OVERFLOW macros return 1 if the corresponding C operators
+ might not yield numerically correct answers due to arithmetic overflow.
+ The INT__WRAPV macros also store the loworder bits of the answer.
+ These macros work correctly on all known practical hosts, and do not rely
+ on undefined behavior due to signed arithmetic overflow.
+
+ Example usage, assuming A and B are long int:
+
+ if (INT_MULTIPLY_OVERFLOW (a, b))
+ printf ("result would overflow\n");
+ else
+ printf ("result is %ld (no overflow)\n", a * b);
+
+ Example usage with WRAPV flavor:
+
+ long int result;
+ bool overflow = INT_MULTIPLY_WRAPV (a, b, &result);
+ printf ("result is %ld (%s)\n", result,
+ overflow ? "after overflow" : "no overflow");
+
+ Restrictions on these macros:
+
+ These macros do not check for all possible numerical problems or
+ undefined or unspecified behavior: they do not check for division
+ by zero, for bad shift counts, or for shifting negative numbers.
+
+ These macros may evaluate their arguments zero or multiple times, so the
+ arguments should not have side effects.
+
+ The WRAPV macros are not constant expressions. They support only
+ +, binary , and *. The result type must be signed.
+
+ These macros are tuned for their last argument being a constant.
+
+ Return 1 if the integer expressions A * B, A  B, A, A * B, A / B,
+ A % B, and A << B would overflow, respectively. */
+
+#define INT_ADD_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
+#define INT_SUBTRACT_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
+#if _GL_HAS_BUILTIN_OVERFLOW_P
+# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a)
+#else
+# define INT_NEGATE_OVERFLOW(a) \
+ INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+#endif
+#define INT_MULTIPLY_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
+#define INT_DIVIDE_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)
+#define INT_REMAINDER_OVERFLOW(a, b) \
+ _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW)
+#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
+ INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
+ _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+
+/* Return 1 if the expression A B would overflow,
+ where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,
+ assuming MIN and MAX are the minimum and maximum for the result type.
+ Arguments should be free of side effects. */
+#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
+ op_result_overflow (a, b, \
+ _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
+ _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))
+
+/* Store the loworder bits of A + B, A  B, A * B, respectively, into *R.
+ Return 1 if the result overflows. See above for restrictions. */
+#define INT_ADD_WRAPV(a, b, r) \
+ _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW)
+#define INT_SUBTRACT_WRAPV(a, b, r) \
+ _GL_INT_OP_WRAPV (a, b, r, , __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW)
+#define INT_MULTIPLY_WRAPV(a, b, r) \
+ _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW)
+
+/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See:
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
+ https://llvm.org/bugs/show_bug.cgi?id=25390
+ For now, assume all versions of GCClike compilers generate bogus
+ warnings for _Generic. This matters only for older compilers that
+ lack __builtin_add_overflow. */
+#if __GNUC__
+# define _GL__GENERIC_BOGUS 1
+#else
+# define _GL__GENERIC_BOGUS 0
+#endif
+
+/* Store the loworder bits of A B into *R, where OP specifies
+ the operation. BUILTIN is the builtin operation, and OVERFLOW the
+ overflow predicate. Return 1 if the result overflows. See above
+ for restrictions. */
+#if _GL_HAS_BUILTIN_OVERFLOW
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r)
+#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+ (_Generic \
+ (*(r), \
+ signed char: \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ signed char, SCHAR_MIN, SCHAR_MAX), \
+ short int: \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ short int, SHRT_MIN, SHRT_MAX), \
+ int: \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ int, INT_MIN, INT_MAX), \
+ long int: \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+ long int, LONG_MIN, LONG_MAX), \
+ long long int: \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+ long long int, LLONG_MIN, LLONG_MAX)))
+#else
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+ (sizeof *(r) == sizeof (signed char) \
+ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ signed char, SCHAR_MIN, SCHAR_MAX) \
+ : sizeof *(r) == sizeof (short int) \
+ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ short int, SHRT_MIN, SHRT_MAX) \
+ : sizeof *(r) == sizeof (int) \
+ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+ int, INT_MIN, INT_MAX) \
+ : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
+# ifdef LLONG_MAX
+# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+ (sizeof *(r) == sizeof (long int) \
+ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+ long int, LONG_MIN, LONG_MAX) \
+ : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+ long long int, LLONG_MIN, LLONG_MAX))
+# else
+# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+ long int, LONG_MIN, LONG_MAX)
+# endif
+#endif
+
+/* Store the loworder bits of A B into *R, where the operation
+ is given by OP. Use the unsigned type UT for calculation to avoid
+ overflow problems. *R's type is T, with extrema TMIN and TMAX.
+ T must be a signed integer type. Return 1 if the result overflows. */
+#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
+ (sizeof ((a) op (b)) < sizeof (t) \
+ ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \
+ : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax))
+#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \
+ ((overflow (a, b) \
+  (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \
+  (tmax) < ((a) op (b))) \
+ ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
+ : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
+
+/* Return the loworder bits of A B, where the operation is given
+ by OP. Use the unsigned type UT for calculation to avoid undefined
+ behavior on signed integer overflow, and convert the result to type T.
+ UT is at least as wide as T and is no narrower than unsigned int,
+ T is two's complement, and there is no padding or trap representations.
+ Assume that converting UT to T yields the loworder bits, as is
+ done in all known two'scomplement C compilers. E.g., see:
+ https://gcc.gnu.org/onlinedocs/gcc/Integersimplementation.html
+
+ According to the C standard, converting UT to T yields an
+ implementationdefined result or signal for values outside T's
+ range. However, code that works around this theoretical problem
+ runs afoul of a compiler bug in Oracle Studio 12.3 x86. See:
+ https://lists.gnu.org/r/buggnulib/201704/msg00049.html
+ As the compiler bug is real, don't try to work around the
+ theoretical problem. */
+
+#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
+ ((t) ((ut) (a) op (ut) (b)))
+
+#endif /* _GL_INTPROPS_H */
diff git a/include/verify.h b/include/verify.h
new file mode 100644
index 0000000000..00e78d3f8c
 /dev/null
+++ b/include/verify.h
@@ 0,0 +1,2 @@
+/* Gnulib , simplified by assuming GCC 4.6 or later. */
+#define verify(R) _Static_assert (R, "verify (" #R ")")
diff git a/time/mktimeinternal.h b/time/mktimeinternal.h
new file mode 100644
index 0000000000..ba1d9c7aab
 /dev/null
+++ b/time/mktimeinternal.h
@@ 0,0 +1 @@
+typedef time_t mktime_offset_t;
diff git a/time/mktime.c b/time/mktime.c
index 5f038a212f..4ff74901e4 100644
 a/time/mktime.c
+++ b/time/mktime.c
@@ 15,13 +15,30 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
 . */
+ . */
/* Define this to have a standalone program to test this implementation of
+/* Define this to 1 to have a standalone program to test this implementation of
mktime. */
/* #define DEBUG_MKTIME 1 */
+#ifndef DEBUG_MKTIME
+# define DEBUG_MKTIME 0
+#endif
#ifndef _LIBC
+/* The following macros influence what gets defined when this file is compiled:
+
+ Macro/expression Which gnulib module This compilation unit
+ should define
+
+ _LIBC (glibc proper) mktime
+
+ NEED_MKTIME_WORKING mktime rpl_mktime
+  NEED_MKTIME_WINDOWS
+
+ NEED_MKTIME_INTERNAL mktimeinternal mktime_internal
+
+ DEBUG_MKTIME (defined manually) my_mktime, main
+ */
+
+#if !defined _LIBC && !DEBUG_MKTIME
# include
#endif
@@ 35,114 +52,128 @@
#include
#include
+#include
+#include
+#include
#include /* For the real memcpy prototype. */
+#include
+#include
#if defined DEBUG_MKTIME && DEBUG_MKTIME
+#if 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 compiletime or
 easily eliminated at runtime.

 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
+#ifndef NEED_MKTIME_INTERNAL
+# define NEED_MKTIME_INTERNAL 0
+#endif
+#ifndef NEED_MKTIME_WINDOWS
+# define NEED_MKTIME_WINDOWS 0
+#endif
+#ifndef NEED_MKTIME_WORKING
+# define NEED_MKTIME_WORKING DEBUG_MKTIME
+#endif
+
+#include "mktimeinternal.h"
+
+#ifndef _LIBC
+static void
+my_tzset (void)
+{
+# if NEED_MKTIME_WINDOWS
+ /* Rectify the value of the environment variable TZ.
+ There are four possible kinds of such values:
+  Traditional US time zone names, e.g. "PST8PDT". Syntax: see
+
+  Time zone names based on geography, that contain one or more
+ slashes, e.g. "Europe/Moscow".
+  Time zone names based on geography, without slashes, e.g.
+ "Singapore".
+  Time zone names that contain explicit DST rules. Syntax: see
+
+ The Microsoft CRT understands only the first kind. It produces incorrect
+ results if the value of TZ is of the other kinds.
+ But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
+ of the second kind for most geographies, or of the first kind in a few
+ other geographies. If it is of the second kind, neutralize it. For the
+ Microsoft CRT, an absent or empty TZ means the time zone that the user
+ has set in the Windows Control Panel.
+ If the value of TZ is of the third or fourth kind  Cygwin programs
+ understand these syntaxes as well , it does not matter whether we
+ neutralize it or not, since these values occur only when a Cygwin user
+ has set TZ explicitly; this case is 1. rare and 2. under the user's
+ responsibility. */
+ const char *tz = getenv ("TZ");
+ if (tz != NULL && strchr (tz, '/') != NULL)
+ _putenv ("TZ=");
+# elif HAVE_TZSET
+ tzset ();
# endif
+}
+# undef __tzset
+# define __tzset() my_tzset ()
#endif
/* Verify a requirement at compiletime (unlike assert, which is runtime). */
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : 1]; }
+#if defined _LIBC  NEED_MKTIME_WORKING  NEED_MKTIME_INTERNAL
+
+/* 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. */
/* A signed type that is at least one bit wider than int. */
#if INT_MAX <= LONG_MAX / 2
+#if INT_MAX <= LONG_MAX / 3 / 366 / 24 / 60 / 60
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);
+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. 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.
+ 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 implementationdefined if A < 0. Some
implementations (e.g., UNICOS 9.0 on a Cray YMP 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)));
+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 (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
+verify (TM_YEAR_BASE % 100 == 0);
/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
static int
+/* 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.
@@ 166,20 +197,9 @@ const unsigned short int __mon_yday[2][13] =
};
#ifndef _LIBC
/* Portable standalone applications should supply a that
 declares a POSIXcompliant localtime_r, for the benefit of older
 implementations that lack localtime_r or have a nonstandard one.
 See the gnulib time_r module for one way to implement this. */
# undef __localtime_r
# define __localtime_r localtime_r
# define __mktime_internal mktime_internal
# include "mktimeinternal.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
+/* 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);
@@ 187,107 +207,68 @@ isdst_differ (int a, int b)
/* Return an integer value measuring (YEAR1YDAY1 HOUR1:MIN1:SEC1) 
(YEAR0YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
 were not adjusted between the time stamps.
+ were not adjusted between the timestamps.
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. */
+ 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 time_t
+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 (C99_integer_division, 1 / 2 == 0);
+ 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 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 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;
+ /* 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. */
static time_t
time_t_avg (time_t a, time_t b)
+/* 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 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 shr (a, 1) + shr (b, 1) + ((a  b) & 1);
}
/* Return a time_t value corresponding to (YEARYDAY HOUR:MIN:SEC),
 assuming that *T corresponds to *TP and that no clock adjustments
+ 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
+ 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 inrange 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,
 const time_t *t, const struct tm *tp)
+ long_int 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;
+ 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
@@ 295,32 +276,51 @@ guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
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 springforward 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));
+ 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 inrange value and then convert that. */
+ it is the nearest inrange 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 *),
 time_t *t, struct tm *tp)
+ long_int *t, struct tm *tp)
{
 struct tm *r = convert (t, 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)
{
 time_t bad = *t;
 time_t ok = 0;
+ long_int bad = *t;
+ long_int ok = 0;
 /* BAD is a known unconvertible time_t, and OK is a known good one.
+ /* 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 (bad != ok + (bad < 0 ? 1 : 1))
+ while (true)
{
 time_t mid = *t = time_t_avg (ok, bad);
 r = convert (t, tp);
+ 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
@@ 331,8 +331,7 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
{
/* The last conversion attempt failed;
revert to the most recent successful attempt. */
 *t = ok;
 r = convert (t, tp);
+ r = convert_time (convert, ok, tp);
}
}
@@ 349,9 +348,9 @@ ranged_convert (struct tm *(*convert) (const time_t *, struct tm *),
time_t
__mktime_internal (struct tm *tp,
struct tm *(*convert) (const time_t *, struct tm *),
 time_t *offset)
+ mktime_offset_t *offset)
{
 time_t t, gt, t0, t1, t2;
+ long_int t, gt, t0, t1, t2, dt;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
@@ 381,9 +380,7 @@ __mktime_internal (struct tm *tp,
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. */
+ the remaining code handles overflows correctly. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
@@ 393,7 +390,8 @@ __mktime_internal (struct tm *tp,
long_int lmday = mday;
long_int yday = mon_yday + lmday;
 time_t guessed_offset = *offset;
+ mktime_offset_t off = *offset;
+ int negative_offset_guess;
int sec_requested = sec;
@@ 410,71 +408,14 @@ __mktime_internal (struct tm *tp,
/* Invert CONVERT by probing. First assume the same offset as last
time. */
+ INT_SUBTRACT_WRAPV (0, off, &negative_offset_guess);
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;
 }
 }
+ 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,
+ (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)
@@ 531,65 +472,70 @@ __mktime_internal (struct tm *tp,
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;
 }
 }
+ {
+ 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:
 *offset = guessed_offset + t  t0;
+ /* Set *OFFSET to the loworder 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. */
 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))
+ 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;
 t = t2;
}
*tp = tm;
return t;
}
+#endif /* _LIBC  NEED_MKTIME_WORKING  NEED_MKTIME_INTERNAL */
/* 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;
+#if defined _LIBC  NEED_MKTIME_WORKING  NEED_MKTIME_WINDOWS
/* Convert *TP to a time_t value. */
time_t
mktime (struct tm *tp)
{
#ifdef _LIBC
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
time zone names contained in the external variable 'tzname' shall
be set as if the tzset() function had been called. */
__tzset ();
#endif
+# if defined __LIBC  NEED_MKTIME_WORKING
+ static mktime_offset_t localtime_offset;
return __mktime_internal (tp, __localtime_r, &localtime_offset);
+# else
+# undef mktime
+ return mktime (tp);
+# endif
}
+#endif /* _LIBC  NEED_MKTIME_WORKING  NEED_MKTIME_WINDOWS */
#ifdef weak_alias
weak_alias (mktime, timelocal)
@@ 600,7 +546,7 @@ libc_hidden_def (mktime)
libc_hidden_weak (timelocal)
#endif
#if defined DEBUG_MKTIME && DEBUG_MKTIME
+#if DEBUG_MKTIME
static int
not_equal_tm (const struct tm *a, const struct tm *b)
@@ 652,6 +598,14 @@ main (int argc, char **argv)
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)
@@ 665,12 +619,7 @@ main (int argc, char **argv)
tm.tm_isdst = argc == 3 ? 1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
 lt = localtime (&tl);
 if (lt)
 {
 tml = *lt;
 lt = &tml;
 }
+ lt = localtime_r (&tl, &tml);
printf ("mktime returns %ld == ", (long int) tl);
print_tm (&tmk);
printf ("\n");
@@ 685,16 +634,16 @@ main (int argc, char **argv)
if (argc == 4)
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
 lt = localtime (&tl);
+ lt = localtime_r (&tl, &tml);
if (lt)
{
 tmk = tml = *lt;
+ tmk = tml;
tk = mktime (&tmk);
status = check_result (tk, tmk, tl, &tml);
}
else
{
 printf ("localtime (%ld) yields 0\n", (long int) tl);
+ printf ("localtime_r (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;
@@ 705,16 +654,16 @@ main (int argc, char **argv)
for (tl = from; by < 0 ? to <= tl : tl <= to; tl = tl1)
{
/* Null benchmark. */
 lt = localtime (&tl);
+ lt = localtime_r (&tl, &tml);
if (lt)
{
 tmk = tml = *lt;
+ tmk = tml;
tk = tl;
status = check_result (tk, tmk, tl, &tml);
}
else
{
 printf ("localtime (%ld) yields 0\n", (long int) tl);
+ printf ("localtime_r (%ld) yields 0\n", (long int) tl);
status = 1;
}
tl1 = tl + by;
diff git a/time/timegm.c b/time/timegm.c
index fb720e2d7d..229fff23c6 100644
 a/time/timegm.c
+++ b/time/timegm.c
@@ 17,31 +17,18 @@
License along with the GNU C Library; if not, see
. */
#ifdef HAVE_CONFIG_H
+#ifndef _LIBC
# include
#endif
#ifdef _LIBC
# include
#else
# include "timegm.h"

/* Portable standalone applications should supply a "time_r.h" that
 declares a POSIXcompliant gmtime_r, for the benefit of older
 implementations that lack gmtime_r or have a nonstandard one.
 See the gnulib time_r module for one way to implement this. */
# include
# undef __gmtime_r
# define __gmtime_r gmtime_r
time_t __mktime_internal (struct tm *,
 struct tm * (*) (time_t const *, struct tm *),
 time_t *);
#endif
+#include
+
+#include "mktimeinternal.h"
time_t
timegm (struct tm *tmp)
{
 static time_t gmtime_offset;
+ static mktime_offset_t gmtime_offset;
tmp>tm_isdst = 0;
return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
}