https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68120
Bug ID: 68120 Summary: can't easily deal with integer overflow at compile time Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: eggert at gnu dot org Target Milestone: --- This is a followup to Bug#61129, which asked for integer-overflow-detecting arithmetic intrinsics. We have them now (thanks!) but I'm running into some problems using them. The Gnulib intprops module defines macros to check for integer overflow, e.g., INT_ADD_OVERFLOW (a, b) returns 1 if the C expression A+B would overflow. These macros are implemented in portable C. I'm trying to use GCC 5's new __builtin_add_overflow etc. functions to speed up their runtime execution. This turns out to be a pain because these macros are used in integer constant expressions, where __builtin_add_overflow etc. cannot be used. 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})) where _GL_INT_ADD_OVERFLOW is a complex macro implemented in Standard C and is a constant expression when its arguments are constant expressions. Although I think this will work, it is ugly, and the macro _GL_INT_ADD_OVERFLOW is complicated. To simplify use of __builtin_add_overflow etc., I suggest extending these builtins as follows. First, allow the 3rd argument to be a null pointer constant of type pointer-to-integer, meaning that the caller only wants to know if the overflow occurred and does not want the low-order bits of the result. E.g., __builtin_add_overflow (a, b, (int *) 0) returns 1 if the mathematical value of A + B does not fit in 'int'. This would allow the above macro to be simplified to: # define INT_ADD_OVERFLOW(a, b) \ __builtin_add_overflow (a, b, (__typeof__ ((a) + (b)) *) 0) Second, allow the 3rd argument to be omitted, as a shorthand for a null pointer to the integer type of A+B. This further simplification would allow the above macro to be simplified to: # define INT_ADD_OVERFLOW(a, b) __builtin_add_overflow (a, b) Third, add a function __builtin_add_wrapv (a, b, c) that acts like __builtin_add_overflow (a, b, c) except that it returns the value that would be stored if C were a non-null pointer. The 3rd argument C is optional here too, with the same semantics as for __builtin_add_overflow. This will let the user get the bottom-order bits of an overflowed value in a constant expression, something that can't be done with the current primitives. The basic idea here is that we need intrinsics that deal with values and that do not require non-null addresses, so that we can use these intrinsics in constant expressions.