Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/time don't depend on integer oveflow wrapping to de...



details:   https://anonhg.NetBSD.org/src/rev/3e81d5c05843
branches:  trunk
changeset: 760871:3e81d5c05843
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jan 14 23:35:07 2011 +0000

description:
don't depend on integer oveflow wrapping to detect it. From Paul Eggert in
the tz mailing list.

diffstat:

 lib/libc/time/Makefile    |   7 ++++++-
 lib/libc/time/localtime.c |  12 ++++++++----
 lib/libc/time/zdump.c     |  35 ++++++++++++++++++++---------------
 lib/libc/time/zic.c       |  18 ++++++------------
 4 files changed, 40 insertions(+), 32 deletions(-)

diffs (194 lines):

diff -r 8ff77ffc3117 -r 3e81d5c05843 lib/libc/time/Makefile
--- a/lib/libc/time/Makefile    Fri Jan 14 18:34:44 2011 +0000
+++ b/lib/libc/time/Makefile    Fri Jan 14 23:35:07 2011 +0000
@@ -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
diff -r 8ff77ffc3117 -r 3e81d5c05843 lib/libc/time/localtime.c
--- a/lib/libc/time/localtime.c Fri Jan 14 18:34:44 2011 +0000
+++ b/lib/libc/time/localtime.c Fri Jan 14 23:35:07 2011 +0000
@@ -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
diff -r 8ff77ffc3117 -r 3e81d5c05843 lib/libc/time/zdump.c
--- a/lib/libc/time/zdump.c     Fri Jan 14 18:34:44 2011 +0000
+++ b/lib/libc/time/zdump.c     Fri Jan 14 23:35:07 2011 +0000
@@ -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.
diff -r 8ff77ffc3117 -r 3e81d5c05843 lib/libc/time/zic.c
--- a/lib/libc/time/zic.c       Fri Jan 14 18:34:44 2011 +0000
+++ b/lib/libc/time/zic.c       Fri Jan 14 23:35:07 2011 +0000
@@ -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;
 }
 
 /*



Home | Main Index | Thread Index | Old Index