Actually, this problem won't be reported upstream, their code is

just ...

	ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
	ptrdiff_t amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;

which is just fine if you think about it a little,   Unfortunately,
in our zealous effort to never leave a ggc warning unused, and to
treat all of the warnings as fatal errors, that code falls foul of the
"you must not compare an unsigned value with a signed value" warning.

nitems_max is a (signed) largish positive integer (obviously, by
inspection).  If it is less than SIZE_MAX then amax is just nitems_max.
In the unlikely case that size_t has less bits than ptrdiff_t so
SIZE_MAX is smaller, amax is limited to SIZE_MAX (which in that case
is known to fit in the ptrdiff_t and to remain positive).

To pacify gcc (and the way the build system uses it), casts are
required.   Unfortunately the cast that was installed here was to
convert SIZE_MAX to a ptrdiff_t.  Unfortunately when ptrdiff_t has
the same number of bits (or less) as size_t (ie: the common case)
but is signed, (ptrdiff_t)SIZE_MAX is just a fancy way of writing -1.

Rearrange the casting in a way that keeps the original intent
of the code for us (it is actyaly now incorrect if size_t has less
bits than a ptrdiff_t) and keeps gcc happy, all at the same time.

What a mess.
This commit is contained in:
kre 2016-11-05 23:09:37 +00:00
parent 752944af9d
commit edb49bae9b

View File

@ -1,4 +1,4 @@
/* $NetBSD: zic.c,v 1.66 2016/11/05 22:21:48 kre Exp $ */
/* $NetBSD: zic.c,v 1.67 2016/11/05 23:09:37 kre 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.66 2016/11/05 22:21:48 kre Exp $");
__RCSID("$NetBSD: zic.c,v 1.67 2016/11/05 23:09:37 kre Exp $");
#endif /* !defined lint */
#include "private.h"
@ -452,14 +452,9 @@ growalloc(void *ptr, size_t itemsize, ptrdiff_t nitems, ptrdiff_t *nitems_alloc)
if (nitems < *nitems_alloc)
return ptr;
else {
#define IMAX (INT_MAX < SIZE_MAX ? INT_MAX : (int)SIZE_MAX)
#if 0
ptrdiff_t nitems_max = PTRDIFF_MAX - WORK_AROUND_QTBUG_53071;
ptrdiff_t amax = nitems_max < (ptrdiff_t)SIZE_MAX ?
nitems_max : (ptrdiff_t)SIZE_MAX;
#endif
int nitems_max = IMAX - WORK_AROUND_QTBUG_53071;
int amax = nitems_max < IMAX ? nitems_max : IMAX;
ptrdiff_t amax = (ptrdiff_t)((size_t)nitems_max < SIZE_MAX ?
(size_t)nitems_max : SIZE_MAX);
if ((amax - 1) / 3 * 2 < *nitems_alloc)
memory_exhausted(_("integer overflow"));
*nitems_alloc += (*nitems_alloc >> 1) + 1;