For the cases where it's more than just nitems * sizeof(item),
maybe it wouldn't be a bad idea to have something like:
static __inline int
MULT_OVERFLOWS(int x, int y)
{
const intmax_t max = 1UL << sizeof(size_t) * 4;
return ((x >= max || y >= max) && x > 0 && SIZE_MAX / x < y);
}
(or maybe a macro version) in some public header someplace,
and associated assertions it where applicable.
> Index: sys/dev/ic/mfi.c
> - sc->sc_bbu_status = malloc(sizeof(*sc->sc_bbu_status) *
> - sizeof(mfi_bbu_indicators), M_DEVBUF, M_WAITOK | M_ZERO);
> + sc->sc_bbu_status = mallocarray(sizeof(mfi_bbu_indicators),
> + sizeof(*sc->sc_bbu_status), M_DEVBUF, M_WAITOK | M_ZERO);
If we're not converting (numeric constant) * sizeof(foo) because it's
cheaper not to and realistically impossible to overflow anyway, then
I think we shouldn't convert sizeof() * sizeof() for the same reason.
>>>> Tedu:
>>>> - shellargp = malloc(4 * sizeof(char *), M_EXEC, M_WAITOK);
>>>> + shellargp = mallocarray(4, sizeof(char *), M_EXEC, M_WAITOK);
>>> Theo:
>>> As for the final diff, I've been giving up on the "known constant"
>>> scenario. It seems expensive.
>> Tedu:
>> Meh. :) I think they can be changed back if necessary; in the mean
>> time it makes it easier to see what's done and what remains.
> Theo:
> It is an extra register window on sparc and sparc64.