Hasso Tepper wrote: > time_t is 64 bits in recent NetBSD versions even on i386 platform, > therefore these assertations fail on it: > > in lib/mktime.c: > verify (long_int_year_and_yday_are_wide_enough, > INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
I'm disabling this assertion; the code seems to be correct also with 64-bit 'time_t'. > in lib/getdate.y: > verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= > LONG_MAX); This one is harder. It has already been reported for QNX [1][2]. [1] http://lists.gnu.org/archive/html/bug-gnulib/2008-01/msg00161.html [2] http://lists.gnu.org/archive/html/bug-gnulib/2009-07/msg00111.html Here is a proposed patch. I checked all uses of 'time_t' in getdate.y and found only two conversions from time_t to 'long int', in the 'relunit' rule: | tSDECIMAL_NUMBER tSEC_UNIT { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } | tUDECIMAL_NUMBER tSEC_UNIT { $$ = RELATIVE_TIME_0; $$.seconds = $1.tv_sec; $$.ns = $1.tv_nsec; } So this patch should handle it. Jim, Eric, opinions? 2009-09-17 Bruno Haible <br...@clisp.org> Make getdate.y compile on QNX and NetBSD 5 / i386. * m4/getdate.m4 (gl_GETDATE): Conditionally define TIME_T_FITS_IN_LONG_INT. * lib/getdate.y (long_time_t): New type. (relative_time): Change type of 'seconds' field to long_time_t. (get_date): Update types of local variables. Check against overflow during conversion from long_time_t to time_t. Reported by Matt Kraai <kr...@ftbfs.org> and Hasso Tepper <ha...@netbsd.org>. --- m4/getdate.m4.orig 2009-09-17 09:28:32.000000000 +0200 +++ m4/getdate.m4 2009-09-17 08:35:40.000000000 +0200 @@ -1,4 +1,4 @@ -# getdate.m4 serial 15 +# getdate.m4 serial 16 dnl Copyright (C) 2002-2006, 2008, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -36,4 +36,18 @@ AC_STRUCT_TIMEZONE AC_REQUIRE([gl_CLOCK_TIME]) AC_REQUIRE([gl_TM_GMTOFF]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ +#include <time.h> /* for time_t */ +#include <limits.h> /* for CHAR_BIT, LONG_MIN, LONG_MAX */ +#define TYPE_MINIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) +#define TYPE_MAXIMUM(t) \ + ((t) ((t) 0 < (t) -1 ? (t) -1 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) +typedef int verify_min[2 * (LONG_MIN <= TYPE_MINIMUM (time_t)) - 1]; +typedef int verify_max[2 * (TYPE_MAXIMUM (time_t) <= LONG_MAX) - 1]; + ]])], + [AC_DEFINE([TIME_T_FITS_IN_LONG_INT], [1], + [Define to 1 if all 'time_t' values fit in a 'long int'.]) + ]) ]) --- lib/getdate.y.orig 2009-09-17 09:28:32.000000000 +0200 +++ lib/getdate.y 2009-09-17 09:24:49.000000000 +0200 @@ -108,12 +108,21 @@ #define HOUR(x) ((x) * 60) -/* Lots of this code assumes time_t and time_t-like values fit into - long int. It also assumes that signed integer overflow silently - wraps around, but there's no portable way to check for that at - compile-time. */ +/* long_time_t is a signed integer type that contains all time_t values. */ verify (TYPE_IS_INTEGER (time_t)); -verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX); +#if TIME_T_FITS_IN_LONG_INT +typedef long int long_time_t; +#else +typedef time_t long_time_t; +#endif + +/* Lots of this code assumes time_t and time_t-like values fit into + long_time_t. */ +verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t) + && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t)); + +/* FIXME: It also assumes that signed integer overflow silently wraps around, + but this is not true any more with recent versions of GCC 4. */ /* An integer value, and the number of digits in its textual representation. */ @@ -146,7 +155,7 @@ long int day; long int hour; long int minutes; - long int seconds; + long_time_t seconds; long int ns; } relative_time; @@ -1502,20 +1511,22 @@ time_t t1 = t0 + d1; long int d2 = 60 * pc.rel.minutes; time_t t2 = t1 + d2; - long int d3 = pc.rel.seconds; - time_t t3 = t2 + d3; + long_time_t d3 = pc.rel.seconds; + long_time_t t3 = t2 + d3; long int d4 = (sum_ns - normalized_ns) / BILLION; - time_t t4 = t3 + d4; + long_time_t t4 = t3 + d4; + time_t t5 = t4; if ((d1 / (60 * 60) ^ pc.rel.hour) | (d2 / 60 ^ pc.rel.minutes) | ((t1 < t0) ^ (d1 < 0)) | ((t2 < t1) ^ (d2 < 0)) | ((t3 < t2) ^ (d3 < 0)) - | ((t4 < t3) ^ (d4 < 0))) + | ((t4 < t3) ^ (d4 < 0)) + | (t5 != t4)) goto fail; - result->tv_sec = t4; + result->tv_sec = t5; result->tv_nsec = normalized_ns; } }