OpenBSD mallocarray
Warner Losh
imp at bsdimp.com
Sun Feb 14 05:53:58 UTC 2016
On Sat, Feb 13, 2016 at 6:21 AM, Ed Schouten <ed at nuxi.nl> wrote:
> Hi there,
>
> 2016-02-01 20:57 GMT+01:00 C Turt <cturt at hardenedbsd.org>:
> > if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
> > nmemb > 0 && SIZE_MAX / nmemb < size) {
>
> In my opinion functions like these are good additions, as long as we
> make sure that we stop importing garbage expressions like the one
> above. It's already bad enough that we copy-pasted this gobbledygook
> into fread(), fwrite(), calloc(), reallocarray(), etc.
>
> Both the latest versions of Clang and GCC support the following builtins:
>
> bool __builtin_add_overflow(type1 a, type2 b, type3 *res);
> bool __builtin_sub_overflow(type1 a, type2 b, type3 *res);
> bool __builtin_mul_overflow(type1 a, type2 b, type3 *res);
>
> These functions perform addition, subtraction and multiplication,
> returning whether overflow has occurred in the process. This is a lot
> more efficient (and readable) than the expression above, as it simply
> uses the CPU's mul instruction, followed by a jump-on-overflow.
>
> GCC 4.2.1 doesn't support these builtins, but they can easily be
> emulated by using static inline functions that use the code above. If
> we want them to be type generic, we can use <sys/cdefs.h>'s
> __generic(), which either expands to C11's _Generic() or falls back to
> GCC's __builtin_types_compatible_p()/__builtin_choose_expr().
>
> I'd say it would make a lot of sense to add a new header file, e.g.
> <sys/overflow.h>, that adds compiler-independent wrappers for these
> builtins:
>
> #if recent version of GCC/Clang
> #define add_overflow(a, b, res) __builtin_add_overflow(a, b, res)
> #else
> #define add_overflow(a, b, res) (__generic(*(res), unsigned int, ...,
> ...)(a, b, res))
> #endif
>
This actually makes a great deal of sense to me.
Warner
More information about the freebsd-arch
mailing list