This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
mktime.c fixes (part 4 of 6): verify assumptions at compile-time
- From: Paul Eggert <eggert at CS dot UCLA dot EDU>
- To: libc-alpha at sources dot redhat dot com
- Date: 31 Dec 2003 00:41:30 -0800
- Subject: mktime.c fixes (part 4 of 6): verify assumptions at compile-time
This patch fixes mktime.c to verify (at compile-time) some assumptions
that the mktime.c code makes but which POSIX and C89 do not guarantee.
These assumptions are valid on all glibc platforms, and on all hosts
of practical interest to the GNU project, but it's better to document
this stuff in case someone wants to run mktime.c on a weird host.
This patch doesn't affect the runtime code at all.
2003-12-30 Paul Eggert <eggert@twinsun.com>
* time/mktime.c (verify): New macro.
(time_t_is_integer, twos_complement_arithmetic,
right_shift_propagates_sign, base_year_is_a_multiple_of_100,
C99_integer_division): Document these longstanding assumptions in the
code, and verify them at compile-time.
===================================================================
RCS file: RCS/mktime.c,v
retrieving revision 1.51.0.3
retrieving revision 1.51.0.4
diff -pu -r1.51.0.3 -r1.51.0.4
--- mktime.c 2003/12/31 05:59:01 1.51.0.3
+++ mktime.c 2003/12/31 06:10:10 1.51.0.4
@@ -61,8 +61,19 @@
# define TIME_T_MAX TYPE_MAXIMUM (time_t)
#endif
-#define TM_YEAR_BASE 1900
+/* Verify a requirement at compile-time (unlike assert, which is runtime). */
+#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
+
+verify (time_t_is_integer, (time_t) 0.5 == 0);
+verify (twos_complement_arithmetic, -1 == ~1 + 1);
+verify (right_shift_propagates_sign, -1 >> 1 == -1);
+/* The code also assumes that signed integer overflow silently wraps
+ around, but this assumption can't be stated without causing a
+ diagnostic on some hosts. */
+
#define EPOCH_YEAR 1970
+#define TM_YEAR_BASE 1900
+verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
@@ -116,6 +127,8 @@ ydhms_tm_diff (int year, int yday, int h
return 1;
else
{
+ verify (C99_integer_division, -1 / 2 == 0);
+
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow. time_t overflow is OK, since
only the low order bits of the correct time_t answer are needed.