This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v2.1] Use saturated arithmetic for overflow detection.
- From: Paul Eggert <eggert at cs dot ucla dot edu>
- To: OndÅej BÃlka <neleai at seznam dot cz>, Mike Frysinger <vapier at gentoo dot org>
- Cc: libc-alpha at sourceware dot org, "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Tue, 03 Dec 2013 09:43:11 -0800
- Subject: Re: [PATCH v2.1] Use saturated arithmetic for overflow detection.
- Authentication-results: sourceware.org; auth=none
- References: <20131030174502 dot GA18107 at domone dot podge> <20131030183318 dot GA18706 at domone dot podge> <20131101133126 dot GA2546 at domone dot podge> <201311300346 dot 53198 dot vapier at gentoo dot org> <20131203111604 dot GA11582 at domone dot podge>
On 12/03/2013 03:16 AM, OndÅej BÃlka wrote:
> +mul_s (size_t x, size_t y)
The implementation here is slow and complex. It'd be better to use
the underlying hardware arithmetic, which typically supports
double-length products. On the rare hardware that doesn't support
that, let's keep it simple. Something like this, perhaps? You'll
need to arrange for HAVE___INT128 to be configured properly; it should
be 1 on typical 64-bit platforms.
/* An unsigned integer type that is at least twice the width of size_t. */
#if SIZE_MAX >> 31 <= 1
# define double_size_t unsigned long long
#elif SIZE_MAX >> 31 >> 31 >> 1 <= 1 && HAVE___INT128
# define double_size_t unsigned __int128
#endif
static inline __attribute__((always_inline, unused)) size_t
mul_s (size_t x, size_t y)
{
#ifdef double_size_t
double_size_t y1 = y;
double_size_t product = x * y1;
if (__glibc_unlikely (SIZE_MAX < product))
return SIZE_MAX;
return product;
#else
if (__builtin_constant_p (x))
return mul_s (y, x);
if (__glibc_unlikely (x > SIZE_MAX / y))
return SIZE_MAX;
return x * y;
#endif
}
> +static inline __attribute__((always_inline, unused)) size_t
> +add_s (size_t x, size_t y)
> +{
> + /* This check is recognized by gcc */
> + if (__glibc_unlikely (x + y < x))
There's no need for that comment. On the other hand, with my pedantic
hat on, you might want to mention that the above test assumes that
INT_MAX < SIZE_MAX. Perhaps put in a static assertion (doesn't
glibc support _Static_assert yet? if not, just add a comment).