From: Paul Eggert Date: Wed, 23 Oct 2019 20:33:37 +0000 (-0700) Subject: nstrftime: speed up integer overflow checking X-Git-Tag: v1.0~4619 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=56ca994d471611b44829fa89b58747b288fa66fc;p=gnulib.git nstrftime: speed up integer overflow checking * lib/nstrftime.c: Include intprops.h. (INT_STRLEN_BOUND): Remove, as we can use intprops.h’s defn. (__strftime_internal): Use INT_MULTIPLY_WRAPV and INT_ADD_WRAPV instead of doing it by hand. * modules/nstrftime (Depends-on): Add intprops. --- diff --git a/ChangeLog b/ChangeLog index 103befc64a..804294150c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2019-10-23 Paul Eggert + nstrftime: speed up integer overflow checking + * lib/nstrftime.c: Include intprops.h. + (INT_STRLEN_BOUND): Remove, as we can use intprops.h’s defn. + (__strftime_internal): Use INT_MULTIPLY_WRAPV and INT_ADD_WRAPV + instead of doing it by hand. + * modules/nstrftime (Depends-on): Add intprops. + Port better to GCC under macOS Work around macOS header that has ‘#define __has_builtin(x) 0’ when compiled by GCC. Apple really, really doesn’t want you to diff --git a/lib/nstrftime.c b/lib/nstrftime.c index 01db02bfe2..11ad00b10d 100644 --- a/lib/nstrftime.c +++ b/lib/nstrftime.c @@ -68,6 +68,8 @@ extern char *tzname[]; #include #include +#include + #ifndef FALLTHROUGH # if __GNUC__ < 7 # define FALLTHROUGH ((void) 0) @@ -113,13 +115,6 @@ extern char *tzname[]; ? (a) >> (b) \ : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) -/* Bound on length of the string representing an integer type or expression T. - Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485; - add 1 for integer division truncation; add 1 more for a minus sign - if needed. */ -#define INT_STRLEN_BOUND(t) \ - ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2) - #define TM_YEAR_BASE 1900 #ifndef __isleap @@ -704,15 +699,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) width = 0; do { - if (width > INT_MAX / 10 - || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10)) - /* Avoid overflow. */ + if (INT_MULTIPLY_WRAPV (width, 10, &width) + || INT_ADD_WRAPV (width, *f - L_('0'), &width)) width = INT_MAX; - else - { - width *= 10; - width += *f - L_('0'); - } ++f; } while (ISDIGIT (*f)); diff --git a/modules/nstrftime b/modules/nstrftime index b559b5e205..a1ce1b33f6 100644 --- a/modules/nstrftime +++ b/modules/nstrftime @@ -9,6 +9,7 @@ m4/nstrftime.m4 Depends-on: extensions +intprops stdbool time_rz