https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68120

--- Comment #2 from Paul Eggert <eggert at gnu dot org> ---
(In reply to Paul Eggert from comment #0)
> I am working around the problem with macro definitions like this:
> 
>  # define INT_ADD_OVERFLOW(a, b) \
>    (__builtin_constant_p ((a) == (b)) \
>     ? _GL_INT_ADD_OVERFLOW (a, b) \
>     : __builtin_add_overflow (a, b, &(__typeof__ ((a) + (b))) {0}))

Just to follow up on my own bug report, the above approach turned out not to
work, because the resulting macro expands to an expression that is not an
integer constant expression according to GCC's current rules. I eventually gave
up on this approach entirely, and INT_ADD_OVERFLOW (a, b) now expands to this:

  (((((0 * (0 * (b) + (a)) - (1)) < 0) ? - (~ (0 * (0 * (b) + (a)) + (0)) ==
-1) - ((((0 * (0 * (b) + (a)) + (1)) << (sizeof ((0 * (b) + (a)) + 0) * 8 - 2))
- 1) * 2 + 1) : (0 * (0 * (b) + (a)) + (0)))) < 0 ? ((b) < 0 ? (a) < ((((0 * (0
* (b) + (a)) - (1)) < 0) ? - (~ (0 * (0 * (b) + (a)) + (0)) == -1) - ((((0 * (0
* (b) + (a)) + (1)) << (sizeof ((0 * (b) + (a)) + 0) * 8 - 2)) - 1) * 2 + 1) :
(0 * (0 * (b) + (a)) + (0)))) - (b) : ((((0 * (0 * (b) + (a)) - (1)) < 0) ?
((((0 * (0 * (b) + (a)) + (1)) << (sizeof ((0 * (b) + (a)) + 0) * 8 - 2)) - 1)
* 2 + 1) : (0 * (0 * (b) + (a)) - (1)))) - (b) < (a)) : (a) < 0 ? (b) <= (a) +
(b) : (b) < 0 ? (a) <= (a) + (b) : (a) + (b) < (b))

Although this *is* an integer constant expression, it is less nice than a
simple call to __builtin_add_overflow would be, and it generates less-efficient
code in some cases when A and B are not constants.

Reply via email to