tz changes to pacify GCC 4.0.2 on Solaris 8

Paul Eggert eggert at CS.UCLA.EDU
Wed Feb 22 18:23:53 UTC 2006


When compiling the latest tz code with GCC 4.0.2 on Solaris 8 (64-bit), I
got some warnings that looked like this:

zic.c:979: warning: comparison between signed and unsigned
zic.c:1086: warning: comparison between signed and unsigned
asctime.c:106: warning: '0' flag ignored with precision and '%d' printf format

Here are proposed patches to remove all the places where I observed
problems in this area.  Not all the size_t-related problems were
caught by GCC, but I expect other compilers might have similar
complaints, so I figured I might as well fix them all while I was
thinking about it.

Since the affected quantities are all too small to be worried about
overflowing a signed 16-bit quantity on practical machines, I don't
think this patch fixes any real-world bugs or changes any real-world
behavior, except perhaps that it makes the code a bit smaller and
faster on 64-bit hosts because we don't keep converting 64-bit
quantities to 32 bits and back.

===================================================================
RCS file: RCS/private.h,v
retrieving revision 2006.2.0.1
retrieving revision 2006.2.0.2
diff -pu -r2006.2.0.1 -r2006.2.0.2
--- private.h	2006/02/21 21:07:30	2006.2.0.1
+++ private.h	2006/02/22 00:24:05	2006.2.0.2
@@ -236,8 +236,8 @@ extern char *	asctime_r();
 char *		icalloc P((int nelem, int elsize));
 char *		icatalloc P((char * old, const char * new));
 char *		icpyalloc P((const char * string));
-char *		imalloc P((int n));
-void *		irealloc P((void * pointer, int size));
+char *		imalloc P((size_t n));
+void *		irealloc P((void * pointer, size_t size));
 void		icfree P((char * pointer));
 void		ifree P((char * pointer));
 const char *	scheck P((const char * string, const char * format));
===================================================================
RCS file: RCS/ialloc.c,v
retrieving revision 1997.3
retrieving revision 1997.3.0.1
diff -pu -r1997.3 -r1997.3.0.1
--- ialloc.c	1997/03/07 21:06:34	1997.3
+++ ialloc.c	2006/02/22 00:27:00	1997.3.0.1
@@ -12,9 +12,9 @@ static char	elsieid[] = "@(#)ialloc.c	8.
 
 char *
 imalloc(n)
-const int	n;
+const size_t	n;
 {
-	return malloc((size_t) nonzero(n));
+	return malloc(nonzero(n));
 }
 
 char *
@@ -30,11 +30,11 @@ int	elsize;
 void *
 irealloc(pointer, size)
 void * const	pointer;
-const int	size;
+const size_t	size;
 {
 	if (pointer == NULL)
 		return imalloc(size);
-	return realloc((void *) pointer, (size_t) nonzero(size));
+	return realloc((void *) pointer, nonzero(size));
 }
 
 char *
@@ -43,7 +43,7 @@ char * const		old;
 const char * const	new;
 {
 	register char *	result;
-	register int	oldsize, newsize;
+	register size_t	oldsize, newsize;
 
 	newsize = (new == NULL) ? 0 : strlen(new);
 	if (old == NULL)
===================================================================
RCS file: RCS/localtime.c,v
retrieving revision 2006.2.0.1
retrieving revision 2006.2.0.2
diff -pu -r2006.2.0.1 -r2006.2.0.2
--- localtime.c	2006/02/21 21:07:30	2006.2.0.1
+++ localtime.c	2006/02/22 00:24:05	2006.2.0.2
@@ -340,8 +340,9 @@ register const int		doextend;
 	register const char *		p;
 	register int			i;
 	register int			fid;
-	register int			stored;
-	register int			nread;
+	register int			read_return;
+	register size_t			stored;
+	register size_t			nread;
 	union {
 		struct tzhead	tzhead;
 		char		buf[2 * sizeof(struct tzhead) +
@@ -385,12 +386,14 @@ register const int		doextend;
 		if ((fid = open(name, OPEN_MODE)) == -1)
 			return -1;
 	}
-	nread = read(fid, u.buf, sizeof u.buf);
-	if (close(fid) < 0 || nread <= 0)
+	read_return = read(fid, u.buf, sizeof u.buf);
+	if (close(fid) < 0 || read_return <= 0)
 		return -1;
+	nread = read_return;
 	for (stored = 4; stored <= 8; stored *= 2) {
 		int		ttisstdcnt;
 		int		ttisgmtcnt;
+		size_t		j;
 
 		ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
 		ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
@@ -511,12 +514,12 @@ register const int		doextend;
 		if (u.tzhead.tzh_version[0] == '\0')
 			break;
 		nread -= p - u.buf;
-		for (i = 0; i < nread; ++i)
-			u.buf[i] = p[i];
+		for (j = 0; j < nread; ++j)
+			u.buf[j] = p[j];
 		/*
 		** If this is a narrow integer time_t system, we're done.
 		*/
-		if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
+		if (stored >= sizeof(time_t) && TYPE_INTEGRAL(time_t))
 			break;
 	}
 	if (doextend && nread > 2 &&
===================================================================
RCS file: RCS/scheck.c,v
retrieving revision 2006.2
retrieving revision 2006.2.0.1
diff -pu -r2006.2 -r2006.2.0.1
--- scheck.c	2006/02/20 15:08:17	2006.2
+++ scheck.c	2006/02/22 00:24:05	2006.2.0.1
@@ -23,7 +23,7 @@ const char * const	format;
 	result = "";
 	if (string == NULL || format == NULL)
 		return result;
-	fbuf = imalloc((int) (2 * strlen(format) + 4));
+	fbuf = imalloc(2 * strlen(format) + 4);
 	if (fbuf == NULL)
 		return result;
 	fp = format;
===================================================================
RCS file: RCS/zic.c,v
retrieving revision 2006.2
retrieving revision 2006.2.0.1
diff -pu -r2006.2 -r2006.2.0.1
--- zic.c	2006/02/20 15:08:17	2006.2
+++ zic.c	2006/02/22 00:24:05	2006.2.0.1
@@ -167,8 +167,8 @@ static int		leapseen;
 static int		leapminyear;
 static int		leapmaxyear;
 static int		linenum;
-static int		max_abbrvar_len;
-static int		max_format_len;
+static size_t		max_abbrvar_len;
+static size_t		max_format_len;
 static zic_t		max_time;
 static int		max_year;
 static zic_t		min_time;
@@ -979,7 +979,7 @@ const int		nfields;
 	if (max_abbrvar_len < strlen(r.r_abbrvar))
 		max_abbrvar_len = strlen(r.r_abbrvar);
 	rules = (struct rule *) (void *) erealloc((char *) rules,
-		(int) ((nrules + 1) * sizeof *rules));
+		(nrules + 1) * sizeof *rules);
 	rules[nrules++] = r;
 }
 
@@ -996,7 +996,7 @@ const int		nfields;
 		return FALSE;
 	}
 	if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) {
-		buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT)));
+		buf = erealloc(buf, 132 + strlen(TZDEFAULT));
 		(void) sprintf(buf,
 _("\"Zone %s\" line and -l option are mutually exclusive"),
 			TZDEFAULT);
@@ -1004,7 +1004,7 @@ _("\"Zone %s\" line and -l option are mu
 		return FALSE;
 	}
 	if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) {
-		buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES)));
+		buf = erealloc(buf, 132 + strlen(TZDEFRULES));
 		(void) sprintf(buf,
 _("\"Zone %s\" line and -p option are mutually exclusive"),
 			TZDEFRULES);
@@ -1014,7 +1014,7 @@ _("\"Zone %s\" line and -p option are mu
 	for (i = 0; i < nzones; ++i)
 		if (zones[i].z_name != NULL &&
 			strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) {
-				buf = erealloc(buf, (int) (132 +
+				buf = erealloc(buf, (132 +
 					strlen(fields[ZF_NAME]) +
 					strlen(zones[i].z_filename)));
 				(void) sprintf(buf,
@@ -1112,7 +1112,7 @@ const int		iscont;
 		}
 	}
 	zones = (struct zone *) (void *) erealloc((char *) zones,
-		(int) ((nzones + 1) * sizeof *zones));
+		(nzones + 1) * sizeof *zones);
 	zones[nzones++] = z;
 	/*
 	** If there was an UNTIL field on this line,
@@ -1249,7 +1249,7 @@ const int		nfields;
 	l.l_from = ecpyalloc(fields[LF_FROM]);
 	l.l_to = ecpyalloc(fields[LF_TO]);
 	links = (struct link *) (void *) erealloc((char *) links,
-		(int) ((nlinks + 1) * sizeof *links));
+		(nlinks + 1) * sizeof *links);
 	links[nlinks++] = l;
 }
 
@@ -1557,7 +1557,7 @@ const char * const	string;
 		++leapi32;
 	}
 	fullname = erealloc(fullname,
-		(int) (strlen(directory) + 1 + strlen(name) + 1));
+		strlen(directory) + 1 + strlen(name) + 1);
 	(void) sprintf(fullname, "%s/%s", directory, name);
 	/*
 	** Remove old file, if any, to snap links.
@@ -1942,8 +1942,8 @@ const int			zonecount;
 	register char *			startbuf;
 	register char *			ab;
 	register char *			envvar;
-	register int			max_abbr_len;
-	register int			max_envvar_len;
+	register size_t			max_abbr_len;
+	register size_t			max_envvar_len;
 
 	max_abbr_len = 2 + max_format_len + max_abbrvar_len;
 	max_envvar_len = 2 * max_abbr_len + 5 * 9;
@@ -2310,7 +2310,7 @@ const char * const	type;
 
 	if (type == NULL || *type == '\0')
 		return TRUE;
-	buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type)));
+	buf = erealloc(buf, 132 + strlen(yitcommand) + strlen(type));
 	(void) sprintf(buf, "%s %d %s", yitcommand, year, type);
 	result = system(buf);
 	if (WIFEXITED(result)) switch (WEXITSTATUS(result)) {
@@ -2401,7 +2401,7 @@ register char *	cp;
 	if (cp == NULL)
 		return NULL;
 	array = (char **) (void *)
-		emalloc((int) ((strlen(cp) + 1) * sizeof *array));
+		emalloc((strlen(cp) + 1) * sizeof *array);
 	nsubs = 0;
 	for ( ; ; ) {
 		while (isascii((unsigned char) *cp) &&
===================================================================
RCS file: RCS/asctime.c,v
retrieving revision 2006.2
retrieving revision 2006.2.0.1
diff -pu -r2006.2 -r2006.2.0.1
--- asctime.c	2006/02/20 15:08:17	2006.2
+++ asctime.c	2006/02/22 00:24:05	2006.2.0.1
@@ -37,14 +37,24 @@ static char	elsieid[] = "@(#)asctime.c	8
 ** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year,
 ** but many implementations pad anyway; most likely the standards are buggy.
 */
+#ifdef __GNUC__
+/* Avoid "warning: '0' flag ignored with precision and '%d' printf format".  */
+#define ASCTIME_FMT	"%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n"
+#else
 #define ASCTIME_FMT	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n"
+#endif
 /*
 ** For years that are more than four digits we put extra spaces before the year
 ** so that code trying to overwrite the newline won't end up overwriting
 ** a digit within a year and truncating the year (operating on the assumption
 ** that no output is better than wrong output).
 */
+#ifdef __GNUC__
+/* Avoid "warning: '0' flag ignored with precision and '%d' printf format".  */
+#define ASCTIME_FMT_B	"%.3s %.3s%3d %2.2d:%2.2d:%2.2d     %s\n"
+#else
 #define ASCTIME_FMT_B	"%.3s %.3s%3d %02.2d:%02.2d:%02.2d     %s\n"
+#endif
 
 #define STD_ASCTIME_BUF_SIZE	26
 /*



More information about the tz mailing list