This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/68120] can't easily deal with integer overflow at compile time
- From: "eggert at gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 18 Dec 2015 17:41:52 +0000
- Subject: [Bug c/68120] can't easily deal with integer overflow at compile time
- Auto-submitted: auto-generated
- References: <bug-68120-4 at http dot gcc dot gnu dot org/bugzilla/>
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.