Commit b059c6b5 authored by Paul Eggert's avatar Paul Eggert

Merge from gnulib.

This incorporates:
2015-10-30 intprops: add WRAPV and const flavors for GCC 5
2015-10-25 stdalign: port to Sun C 5.9
* doc/misc/texinfo.tex, lib/intprops.h, lib/
Copy from gnulib.
parent e11aaee2
This diff is collapsed.
......@@ -263,22 +263,31 @@
: (a) % - (b)) \
== 0)
/* Integer overflow checks.
/* Check for integer overflow, and report low order bits of answer.
The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators
might not yield numerically correct answers due to arithmetic overflow.
They work correctly on all known practical hosts, and do not rely
The INT_<op>_WRAPV macros return the low-order bits of the answer.
For example, INT_ADD_WRAPV (INT_MAX, 1) returns INT_MIN on a two's
complement host, even if INT_MAX + 1 would trap.
These macros work correctly on all known practical hosts, and do not rely
on undefined behavior due to signed arithmetic overflow.
Example usage:
long int i = ...;
long int j = ...;
printf ("multiply would overflow");
printf ("product is %ld", i * j);
long int a = ...;
long int b = ...;
long int result = INT_MULTIPLY_WRAPV (a, b);
printf ("result is %ld (%s)\n", result,
INT_MULTIPLY_OVERFLOW (a, b) ? "after overflow" : "no overflow");
enum {
Restrictions on these macros:
These macros do not check for all possible numerical problems or
undefined or unspecified behavior: they do not check for division
......@@ -287,18 +296,35 @@
These macros may evaluate their arguments zero or multiple times, so the
arguments should not have side effects.
On non-GCC-compatible compilers that do not support C11, the type
of INT_<op>_WRAPV (A, B) might differ from the native type of (A op
B), so it is wise to convert the result to the native type. Such a
conversion is safe and cannot trap.
For runtime efficiency GCC 5 and later has builtin functions for +,
-, * when doing integer overflow checking or wraparound arithmetic.
Unfortunately, these builtins require nonnull pointer arguments and
so cannot be used in constant expressions; see GCC bug 68120
<>. In constant
expressions, use the macros INT_CONST_ADD_OVERFLOW and
INT_CONST_ADD_WRAPV instead, and similarly for SUBTRACT and
MULTIPLY; these macros avoid the builtins and are slower in
non-constant expressions. Perhaps someday GCC's API for overflow
checking will be improved and we can remove the need for the
INT_CONST_ variants.
These macros are tuned for their last argument being a constant.
Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
A % B, and A << B would overflow, respectively. */
#define INT_ADD_OVERFLOW(a, b) \
#define INT_CONST_ADD_OVERFLOW(a, b) \
#define INT_DIVIDE_OVERFLOW(a, b) \
......@@ -317,4 +343,95 @@
_GL_INT_MINIMUM (0 * (b) + (a)), \
_GL_INT_MAXIMUM (0 * (b) + (a)))
/* Return the low order bits of the integer expressions
A * B, A - B, -A, A * B, A / B, A % B, and A << B, respectively.
See above for restrictions. */
#define INT_CONST_ADD_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, +)
#define INT_DIVIDE_WRAPV(a, b) \
(INT_DIVIDE_OVERFLOW(a, b) ? INT_NEGATE_WRAPV (a) : (a) / (b))
#define INT_REMAINDER_WRAPV(a, b) \
(INT_REMAINDER_OVERFLOW(a, b) ? 0 : (a) % (b))
#define INT_LEFT_SHIFT_WRAPV(a, b) _GL_INT_OP_WRAPV (a, b, <<)
/* Return the low order bits of A <op> B, where OP specifies the operation.
See above for restrictions. */
#if !_GL_HAVE___TYPEOF__ && 201112 <= __STDC_VERSION__
# define _GL_INT_OP_WRAPV(a, b, op) \
_Generic ((a) op (b), \
int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, int), \
long int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int), \
long long int: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, \
long long int), \
default: (a) op (b))
# define _GL_INT_OP_WRAPV(a, b, op) \
(! _GL_INT_SIGNED ((0 * (a)) op (0 * (b))) \
? ((a) op (b)) \
: _GL_EXPR_CAST ((a) op (b), \
(sizeof ((a) op (b)) <= sizeof (int) \
? _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, int) \
: _GL_INT_OP_WRAPV_LONGISH (a, b, op))))
/* Cast to E's type the value of V if possible. Yield V as-is otherwise. */
# if _GL_HAVE___TYPEOF__
# define _GL_EXPR_CAST(e, v) ((__typeof__ (e)) (v))
# else
# define _GL_EXPR_CAST(e, v) (v)
# endif
# ifdef LLONG_MAX
# define _GL_INT_OP_WRAPV_LONGISH(a, b, op) \
(sizeof ((a) op (b)) <= sizeof (long int) \
? _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int) \
: _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long long int))
# else
# define _GL_INT_OP_WRAPV_LONGISH(a, b, op) \
_GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, long int)
# endif
/* Return A <op> B, where the operation is given by OP and the result
type is T. T is a signed integer type that is at least as wide as int.
Do arithmetic using 'unsigned T' to avoid signed integer overflow.
Subtract TYPE_MINIMUM (T) before converting back to T, and add it
back afterwards, to avoid signed overflow during conversion. */
#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, t) \
((unsigned t) (a) op (unsigned t) (b) <= TYPE_MAXIMUM (t) \
? (t) ((unsigned t) (a) op (unsigned t) (b)) \
: ((t) ((unsigned t) (a) op (unsigned t) (b) - TYPE_MINIMUM (t)) \
/* Calls to the INT_<op>_<result> macros are like their INT_CONST_<op>_<result>
counterparts, except they are faster with GCC 5 or later, and they
are not constant expressions due to limitations in the GNU C API. */
#define INT_ADD_OVERFLOW(a, b) \
_GL_OP_OVERFLOW (a, b, INT_CONST_ADD_OVERFLOW, __builtin_add_overflow)
_GL_OP_OVERFLOW (a, b, INT_CONST_SUBTRACT_OVERFLOW, __builtin_sub_overflow)
_GL_OP_OVERFLOW (a, b, INT_CONST_MULTIPLY_OVERFLOW, __builtin_mul_overflow)
#define INT_ADD_WRAPV(a, b) \
_GL_OP_WRAPV (a, b, INT_CONST_ADD_WRAPV, __builtin_add_overflow)
#define INT_SUBTRACT_WRAPV(a, b) \
_GL_OP_WRAPV (a, b, INT_CONST_SUBTRACT_WRAPV, __builtin_sub_overflow)
#define INT_MULTIPLY_WRAPV(a, b) \
_GL_OP_WRAPV (a, b, INT_CONST_MULTIPLY_WRAPV, __builtin_mul_overflow)
#if __GNUC__ < 5
# define _GL_OP_OVERFLOW(a, b, portable, builtin) portable (a, b)
# define _GL_OP_WRAPV(a, b, portable, builtin) portable (a, b)
# define _GL_OP_OVERFLOW(a, b, portable, builtin) \
builtin (a, b, &(__typeof__ ((a) + (b))) {0})
# define _GL_OP_WRAPV(a, b, portable, builtin) \
_GL_OP_WRAPV_GENSYM(a, b, builtin, __gl_wrapv##__COUNTER__)
# define _GL_OP_WRAPV_GENSYM(a, b, builtin, r) \
({__typeof__ ((a) + (b)) r; builtin (a, b, &r); r; })
#endif /* _GL_INTPROPS_H */
......@@ -104,7 +104,7 @@
? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
: __GNUC__) \
|| __HP_cc || __HP_aCC || __IBMC__ || __IBMCPP__ \
|| __ICC || 0x5110 <= __SUNPRO_C)
|| __ICC || 0x590 <= __SUNPRO_C)
# define _Alignas(a) __attribute__ ((__aligned__ (a)))
# elif 1300 <= _MSC_VER
# define _Alignas(a) __declspec (align (a))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment