Module Name: src Committed By: christos Date: Fri Jan 14 23:35:07 UTC 2011
Modified Files: src/lib/libc/time: Makefile localtime.c zdump.c zic.c Log Message: don't depend on integer oveflow wrapping to detect it. From Paul Eggert in the tz mailing list. To generate a diff of this commit: cvs rdiff -u -r1.1.1.1 -r1.2 src/lib/libc/time/Makefile cvs rdiff -u -r1.51 -r1.52 src/lib/libc/time/localtime.c cvs rdiff -u -r1.17 -r1.18 src/lib/libc/time/zdump.c cvs rdiff -u -r1.26 -r1.27 src/lib/libc/time/zic.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/time/Makefile diff -u src/lib/libc/time/Makefile:1.1.1.1 src/lib/libc/time/Makefile:1.2 --- src/lib/libc/time/Makefile:1.1.1.1 Sun Oct 25 12:20:16 2009 +++ src/lib/libc/time/Makefile Fri Jan 14 18:35:07 2011 @@ -110,6 +110,10 @@ # -TTZ_DOMAINDIR=\"/path\" to use "/path" for gettext directory; # the default is system-supplied, typically "/usr/lib/locale" # $(GCC_DEBUG_FLAGS) if you are using GCC and want lots of checking +# $(GCC_OVERFLOW_FLAGS) if you are using GCC 3.4 or later. +# If you are using a compiler other than GCC, and if it defaults to +# undefined behavior on integer overflow, then you need to specify a flag +# saying that integer arithmetic is supposed to wrap around on overflow. # -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1 # if you do not want run time warnings about formats that may cause # year 2000 grief @@ -120,6 +124,7 @@ -Wall -Wcast-qual -Wconversion -Wmissing-prototypes \ -Wnested-externs -Wpointer-arith -Wshadow \ -Wtraditional # -Wstrict-prototypes -Wwrite-strings +GCC_OVERFLOW_FLAGS = -fwrapv # # If you want to use System V compatibility code, add # -DUSG_COMPAT @@ -386,7 +391,7 @@ public: $(ENCHILADA) make maintainer-clean - make "CFLAGS=$(GCC_DEBUG_FLAGS)" + make "CFLAGS=$(GCC_DEBUG_FLAGS) $(GCC_OVERFLOW_FLAGS)" -mkdir /tmp/,tzpublic -for i in $(TDATA) ; do zic -v -d /tmp/,tzpublic $$i 2>&1 | grep -v "starting year" ; done for i in $(TDATA) ; do zic -d /tmp/,tzpublic $$i || exit; done Index: src/lib/libc/time/localtime.c diff -u src/lib/libc/time/localtime.c:1.51 src/lib/libc/time/localtime.c:1.52 --- src/lib/libc/time/localtime.c:1.51 Wed Jan 5 21:41:34 2011 +++ src/lib/libc/time/localtime.c Fri Jan 14 18:35:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: localtime.c,v 1.51 2011/01/06 02:41:34 christos Exp $ */ +/* $NetBSD: localtime.c,v 1.52 2011/01/14 23:35:07 christos Exp $ */ /* ** This file is in the public domain, so clarified as of @@ -10,7 +10,7 @@ #if 0 static char elsieid[] = "@(#)localtime.c 8.9"; #else -__RCSID("$NetBSD: localtime.c,v 1.51 2011/01/06 02:41:34 christos Exp $"); +__RCSID("$NetBSD: localtime.c,v 1.52 2011/01/14 23:35:07 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -1704,8 +1704,10 @@ int number0; number0 = *number; + if (delta < 0 ? number0 < delta - INT_MIN : INT_MAX - delta < number0) + return 1; *number += delta; - return (*number < number0) != (delta < 0); + return 0; } static int @@ -1714,8 +1716,10 @@ long number0; number0 = *number; + if (delta < 0 ? number0 < delta - LONG_MIN : LONG_MAX - delta < number0) + return 1; *number += delta; - return (*number < number0) != (delta < 0); + return 0; } static int Index: src/lib/libc/time/zdump.c diff -u src/lib/libc/time/zdump.c:1.17 src/lib/libc/time/zdump.c:1.18 --- src/lib/libc/time/zdump.c:1.17 Thu Dec 31 17:49:16 2009 +++ src/lib/libc/time/zdump.c Fri Jan 14 18:35:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: zdump.c,v 1.17 2009/12/31 22:49:16 mlelstv Exp $ */ +/* $NetBSD: zdump.c,v 1.18 2011/01/14 23:35:07 christos Exp $ */ /* ** This file is in the public domain, so clarified as of ** 2009-05-17 by Arthur David Olson. @@ -7,7 +7,7 @@ #include <sys/cdefs.h> #ifndef lint #ifndef NOID -__RCSID("$NetBSD: zdump.c,v 1.17 2009/12/31 22:49:16 mlelstv Exp $"); +__RCSID("$NetBSD: zdump.c,v 1.18 2011/01/14 23:35:07 christos Exp $"); #endif /* !defined NOID */ #endif /* !defined lint */ @@ -26,6 +26,7 @@ #include "stdlib.h" /* for exit, malloc, atoi */ #include <err.h> #include "float.h" /* for FLT_MAX and DBL_MAX */ +#include "limits.h" /* for INT_MAX, LONG_MAX, etc. */ #include "ctype.h" /* for isalpha et al. */ #ifndef isascii #define isascii(x) 1 @@ -431,21 +432,25 @@ } } else if (0 > (time_t) -1) { /* - ** time_t is signed. Assume overflow wraps around. + ** time_t is signed. */ - time_t t = 0; - time_t t1 = 1; - - while (t < t1) { - t = t1; - t1 = 2 * t1 + 1; + if (sizeof (time_t) == sizeof (int)) { + absolute_min_time = INT_MIN; + absolute_max_time = INT_MAX; + } else if (sizeof (time_t) == sizeof (long)) { + absolute_min_time = LONG_MIN; + absolute_max_time = LONG_MAX; +#if defined LLONG_MIN && defined LLONG_MAX + } else if (sizeof (time_t) == sizeof (long long)) { + absolute_min_time = LLONG_MIN; + absolute_max_time = LLONG_MAX; +#endif + } else { + (void) fprintf(stderr, +_("%s: use of -v on system with signed time_t whose extrema are unknown\n"), + progname); + exit(EXIT_FAILURE); } - - absolute_max_time = t; - t = -t; - absolute_min_time = t - 1; - if (t < absolute_min_time) - absolute_min_time = t; } else { /* ** time_t is unsigned. Index: src/lib/libc/time/zic.c diff -u src/lib/libc/time/zic.c:1.26 src/lib/libc/time/zic.c:1.27 --- src/lib/libc/time/zic.c:1.26 Sat Jan 2 05:42:49 2010 +++ src/lib/libc/time/zic.c Fri Jan 14 18:35:07 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: zic.c,v 1.26 2010/01/02 10:42:49 tsutsui Exp $ */ +/* $NetBSD: zic.c,v 1.27 2011/01/14 23:35:07 christos Exp $ */ /* ** This file is in the public domain, so clarified as of ** 2006-07-17 by Arthur David Olson. @@ -10,7 +10,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: zic.c,v 1.26 2010/01/02 10:42:49 tsutsui Exp $"); +__RCSID("$NetBSD: zic.c,v 1.27 2011/01/14 23:35:07 christos Exp $"); #endif /* !defined lint */ static char elsieid[] = "@(#)zic.c 8.20"; @@ -2496,14 +2496,11 @@ const long t1; const long t2; { - register long t; - - t = t1 + t2; - if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + if (t2 < 0 ? t1 < t2 - LONG_MIN : LONG_MAX - t2 < t1) { error(_("time overflow")); exit(EXIT_FAILURE); } - return t; + return t1 + t2; } static zic_t @@ -2511,18 +2508,15 @@ const zic_t t1; const long t2; { - register zic_t t; - if (t1 == max_time && t2 > 0) return max_time; if (t1 == min_time && t2 < 0) return min_time; - t = t1 + t2; - if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + if (t2 < 0 ? t1 < t2 - LONG_MIN : LONG_MAX - t2 < t1) { error(_("time overflow")); exit(EXIT_FAILURE); } - return t; + return t1 + t2; } /*