On Thu, Jun 02, 2016 at 09:23:16AM +0200, Jakub Jelinek wrote:
> Also, perhaps just a documentation thing, it would be good to clarify the
> NULL last argument.  From the POV of generating efficient code, I think we
> should say something that the last argument (for the GNU builtins) must be
> either a pointer to a valid object, or NULL/nullptr constant cast expression
> cast to a pointer type, but nothing else.  That is actually what your patch
> implements.  But, I'd like to make sure that
>   int *p = NULL;
>   if (__builtin_add_overflow (a, b, p))
>     ...
> is actually not valid, otherwise we unnecessarily pessimize many of the GNU
> style calls (those that don't pass &var), where instead of
>   tem = ADD_OVERFLOW (a, b);
>   *p = REALPART_EXPR (tem);
>   ovf = IMAGPART_EXPR (tem);
> we'd need to emit instead
>   tem = ADD_OVERFLOW (a, b);
>   ovf = IMAGPART_EXPR (tem);
>   if (p != NULL)
>     *p = REALPART_EXPR (tem);

Though, perhaps that is too ugly, that it has different semantics for
  __builtin_add_overflow (a, b, (int *) NULL)
and for
  int *p = NULL;
  __builtin_add_overflow (a, b, p)
Maybe the cleanest would be to just add 3 extra builtins, again,
typegeneric,
  __builtin_{add,sub,mul}_overflow_p
where either the arguments would be instead of integertype1, integertype2,
integertype3 * rather integertype1, integertype2, integertype3
and we'd only care about the type, not value, of the last argument,
so use it like __builtin_add_overflow_p (a, b, (__typeof ((a) + (b))) 0)
or handle those 3 similarly to __builtin_va_arg, and use
__builtin_add_overflow_p (a, b, int);
I think I prefer the former though.

        Jakub

Reply via email to