1 | /* intprops-internal.h -- properties of integer types not visible to users
|
---|
2 |
|
---|
3 | Copyright (C) 2001-2022 Free Software Foundation, Inc.
|
---|
4 |
|
---|
5 | This program is free software: you can redistribute it and/or modify it
|
---|
6 | under the terms of the GNU Lesser General Public License as published
|
---|
7 | by the Free Software Foundation; either version 2.1 of the License, or
|
---|
8 | (at your option) any later version.
|
---|
9 |
|
---|
10 | This program is distributed in the hope that it will be useful,
|
---|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
13 | GNU Lesser General Public License for more details.
|
---|
14 |
|
---|
15 | You should have received a copy of the GNU Lesser General Public License
|
---|
16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
---|
17 |
|
---|
18 | #ifndef _GL_INTPROPS_INTERNAL_H
|
---|
19 | #define _GL_INTPROPS_INTERNAL_H
|
---|
20 |
|
---|
21 | #include <limits.h>
|
---|
22 |
|
---|
23 | /* Return a value with the common real type of E and V and the value of V.
|
---|
24 | Do not evaluate E. */
|
---|
25 | #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
|
---|
26 |
|
---|
27 | /* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
|
---|
28 | <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>. */
|
---|
29 | #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
|
---|
30 |
|
---|
31 | /* The extra casts in the following macros work around compiler bugs,
|
---|
32 | e.g., in Cray C 5.0.3.0. */
|
---|
33 |
|
---|
34 | /* True if the real type T is signed. */
|
---|
35 | #define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
---|
36 |
|
---|
37 | /* Return 1 if the real expression E, after promotion, has a
|
---|
38 | signed or floating type. Do not evaluate E. */
|
---|
39 | #define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
|
---|
40 |
|
---|
41 |
|
---|
42 | /* Minimum and maximum values for integer types and expressions. */
|
---|
43 |
|
---|
44 | /* The width in bits of the integer type or expression T.
|
---|
45 | Do not evaluate T. T must not be a bit-field expression.
|
---|
46 | Padding bits are not supported; this is checked at compile-time below. */
|
---|
47 | #define _GL_TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
|
---|
48 |
|
---|
49 | /* The maximum and minimum values for the type of the expression E,
|
---|
50 | after integer promotion. E is not evaluated. */
|
---|
51 | #define _GL_INT_MINIMUM(e) \
|
---|
52 | (_GL_EXPR_SIGNED (e) \
|
---|
53 | ? ~ _GL_SIGNED_INT_MAXIMUM (e) \
|
---|
54 | : _GL_INT_CONVERT (e, 0))
|
---|
55 | #define _GL_INT_MAXIMUM(e) \
|
---|
56 | (_GL_EXPR_SIGNED (e) \
|
---|
57 | ? _GL_SIGNED_INT_MAXIMUM (e) \
|
---|
58 | : _GL_INT_NEGATE_CONVERT (e, 1))
|
---|
59 | #define _GL_SIGNED_INT_MAXIMUM(e) \
|
---|
60 | (((_GL_INT_CONVERT (e, 1) << (_GL_TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
|
---|
61 |
|
---|
62 | /* Work around OpenVMS incompatibility with C99. */
|
---|
63 | #if !defined LLONG_MAX && defined __INT64_MAX
|
---|
64 | # define LLONG_MAX __INT64_MAX
|
---|
65 | # define LLONG_MIN __INT64_MIN
|
---|
66 | #endif
|
---|
67 |
|
---|
68 | /* This include file assumes that signed types are two's complement without
|
---|
69 | padding bits; the above macros have undefined behavior otherwise.
|
---|
70 | If this is a problem for you, please let us know how to fix it for your host.
|
---|
71 | This assumption is tested by the intprops-tests module. */
|
---|
72 |
|
---|
73 | /* Does the __typeof__ keyword work? This could be done by
|
---|
74 | 'configure', but for now it's easier to do it by hand. */
|
---|
75 | #if (2 <= __GNUC__ \
|
---|
76 | || (4 <= __clang_major__) \
|
---|
77 | || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
|
---|
78 | || (0x5110 <= __SUNPRO_C && !__STDC__))
|
---|
79 | # define _GL_HAVE___TYPEOF__ 1
|
---|
80 | #else
|
---|
81 | # define _GL_HAVE___TYPEOF__ 0
|
---|
82 | #endif
|
---|
83 |
|
---|
84 | /* Return 1 if the integer type or expression T might be signed. Return 0
|
---|
85 | if it is definitely unsigned. T must not be a bit-field expression.
|
---|
86 | This macro does not evaluate its argument, and expands to an
|
---|
87 | integer constant expression. */
|
---|
88 | #if _GL_HAVE___TYPEOF__
|
---|
89 | # define _GL_SIGNED_TYPE_OR_EXPR(t) _GL_TYPE_SIGNED (__typeof__ (t))
|
---|
90 | #else
|
---|
91 | # define _GL_SIGNED_TYPE_OR_EXPR(t) 1
|
---|
92 | #endif
|
---|
93 |
|
---|
94 | /* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
|
---|
95 | A should not have side effects, and A's type should be an
|
---|
96 | integer with minimum value MIN and maximum MAX. */
|
---|
97 | #define _GL_INT_NEGATE_RANGE_OVERFLOW(a, min, max) \
|
---|
98 | ((min) < 0 ? (a) < - (max) : 0 < (a))
|
---|
99 |
|
---|
100 | /* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow
|
---|
101 | (A, B, P) work when P is non-null. */
|
---|
102 | #ifdef __EDG__
|
---|
103 | /* EDG-based compilers like nvc 22.1 cannot add 64-bit signed to unsigned
|
---|
104 | <https://bugs.gnu.org/53256>. */
|
---|
105 | # define _GL_HAS_BUILTIN_ADD_OVERFLOW 0
|
---|
106 | #elif defined __has_builtin
|
---|
107 | # define _GL_HAS_BUILTIN_ADD_OVERFLOW __has_builtin (__builtin_add_overflow)
|
---|
108 | /* __builtin_{add,sub}_overflow exists but is not reliable in GCC 5.x and 6.x,
|
---|
109 | see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98269>. */
|
---|
110 | #elif 7 <= __GNUC__
|
---|
111 | # define _GL_HAS_BUILTIN_ADD_OVERFLOW 1
|
---|
112 | #else
|
---|
113 | # define _GL_HAS_BUILTIN_ADD_OVERFLOW 0
|
---|
114 | #endif
|
---|
115 |
|
---|
116 | /* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */
|
---|
117 | #if defined __clang_major__ && __clang_major__ < 14
|
---|
118 | /* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>. */
|
---|
119 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW 0
|
---|
120 | #else
|
---|
121 | # define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW
|
---|
122 | #endif
|
---|
123 |
|
---|
124 | /* True if __builtin_add_overflow_p (A, B, C) works, and similarly for
|
---|
125 | __builtin_sub_overflow_p and __builtin_mul_overflow_p. */
|
---|
126 | #ifdef __EDG__
|
---|
127 | /* In EDG-based compilers like ICC 2021.3 and earlier,
|
---|
128 | __builtin_add_overflow_p etc. are not treated as integral constant
|
---|
129 | expressions even when all arguments are. */
|
---|
130 | # define _GL_HAS_BUILTIN_OVERFLOW_P 0
|
---|
131 | #elif defined __has_builtin
|
---|
132 | # define _GL_HAS_BUILTIN_OVERFLOW_P __has_builtin (__builtin_mul_overflow_p)
|
---|
133 | #else
|
---|
134 | # define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
|
---|
135 | #endif
|
---|
136 |
|
---|
137 | #if (!defined _GL_STDCKDINT_H && 202311 <= __STDC_VERSION__ \
|
---|
138 | && ! (_GL_HAS_BUILTIN_ADD_OVERFLOW && _GL_HAS_BUILTIN_MUL_OVERFLOW))
|
---|
139 | # include <stdckdint.h>
|
---|
140 | #endif
|
---|
141 |
|
---|
142 | /* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
|
---|
143 | Return 1 if the result overflows. Arguments should not have side
|
---|
144 | effects and A, B and *R can be of any integer type other than char,
|
---|
145 | bool, a bit-precise integer type, or an enumeration type. */
|
---|
146 | #if _GL_HAS_BUILTIN_ADD_OVERFLOW
|
---|
147 | # define _GL_INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r)
|
---|
148 | # define _GL_INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r)
|
---|
149 | #elif defined ckd_add && defined ckd_sub && !defined _GL_STDCKDINT_H
|
---|
150 | # define _GL_INT_ADD_WRAPV(a, b, r) ckd_add (r, + (a), + (b))
|
---|
151 | # define _GL_INT_SUBTRACT_WRAPV(a, b, r) ckd_sub (r, + (a), + (b))
|
---|
152 | #else
|
---|
153 | # define _GL_INT_ADD_WRAPV(a, b, r) \
|
---|
154 | _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
|
---|
155 | # define _GL_INT_SUBTRACT_WRAPV(a, b, r) \
|
---|
156 | _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
|
---|
157 | #endif
|
---|
158 | #if _GL_HAS_BUILTIN_MUL_OVERFLOW
|
---|
159 | # if ((9 < __GNUC__ + (3 <= __GNUC_MINOR__) \
|
---|
160 | || (__GNUC__ == 8 && 4 <= __GNUC_MINOR__)) \
|
---|
161 | && !defined __EDG__)
|
---|
162 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) __builtin_mul_overflow (a, b, r)
|
---|
163 | # else
|
---|
164 | /* Work around GCC bug 91450. */
|
---|
165 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) \
|
---|
166 | ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && _GL_EXPR_SIGNED (a) && _GL_EXPR_SIGNED (b) \
|
---|
167 | && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \
|
---|
168 | ? ((void) __builtin_mul_overflow (a, b, r), 1) \
|
---|
169 | : __builtin_mul_overflow (a, b, r))
|
---|
170 | # endif
|
---|
171 | #elif defined ckd_mul && !defined _GL_STDCKDINT_H
|
---|
172 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) ckd_mul (r, + (a), + (b))
|
---|
173 | #else
|
---|
174 | # define _GL_INT_MULTIPLY_WRAPV(a, b, r) \
|
---|
175 | _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)
|
---|
176 | #endif
|
---|
177 |
|
---|
178 | /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See:
|
---|
179 | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
|
---|
180 | https://llvm.org/bugs/show_bug.cgi?id=25390
|
---|
181 | For now, assume all versions of GCC-like compilers generate bogus
|
---|
182 | warnings for _Generic. This matters only for compilers that
|
---|
183 | lack relevant builtins. */
|
---|
184 | #if __GNUC__ || defined __clang__
|
---|
185 | # define _GL__GENERIC_BOGUS 1
|
---|
186 | #else
|
---|
187 | # define _GL__GENERIC_BOGUS 0
|
---|
188 | #endif
|
---|
189 |
|
---|
190 | /* Store the low-order bits of A <op> B into *R, where OP specifies
|
---|
191 | the operation and OVERFLOW the overflow predicate. Return 1 if the
|
---|
192 | result overflows. Arguments should not have side effects,
|
---|
193 | and A, B and *R can be of any integer type other than char, bool, a
|
---|
194 | bit-precise integer type, or an enumeration type. */
|
---|
195 | #if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
|
---|
196 | # define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
|
---|
197 | (_Generic \
|
---|
198 | (*(r), \
|
---|
199 | signed char: \
|
---|
200 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
201 | signed char, SCHAR_MIN, SCHAR_MAX), \
|
---|
202 | unsigned char: \
|
---|
203 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
204 | unsigned char, 0, UCHAR_MAX), \
|
---|
205 | short int: \
|
---|
206 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
207 | short int, SHRT_MIN, SHRT_MAX), \
|
---|
208 | unsigned short int: \
|
---|
209 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
210 | unsigned short int, 0, USHRT_MAX), \
|
---|
211 | int: \
|
---|
212 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
213 | int, INT_MIN, INT_MAX), \
|
---|
214 | unsigned int: \
|
---|
215 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
216 | unsigned int, 0, UINT_MAX), \
|
---|
217 | long int: \
|
---|
218 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
219 | long int, LONG_MIN, LONG_MAX), \
|
---|
220 | unsigned long int: \
|
---|
221 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
222 | unsigned long int, 0, ULONG_MAX), \
|
---|
223 | long long int: \
|
---|
224 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
|
---|
225 | long long int, LLONG_MIN, LLONG_MAX), \
|
---|
226 | unsigned long long int: \
|
---|
227 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
|
---|
228 | unsigned long long int, 0, ULLONG_MAX)))
|
---|
229 | #else
|
---|
230 | /* Store the low-order bits of A <op> B into *R, where OP specifies
|
---|
231 | the operation and OVERFLOW the overflow predicate. If *R is
|
---|
232 | signed, its type is ST with bounds SMIN..SMAX; otherwise its type
|
---|
233 | is UT with bounds U..UMAX. ST and UT are narrower than int.
|
---|
234 | Return 1 if the result overflows. Arguments should not have side
|
---|
235 | effects, and A, B and *R can be of any integer type other than
|
---|
236 | char, bool, a bit-precise integer type, or an enumeration type. */
|
---|
237 | # if _GL_HAVE___TYPEOF__
|
---|
238 | # define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
|
---|
239 | (_GL_TYPE_SIGNED (__typeof__ (*(r))) \
|
---|
240 | ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, st, smin, smax) \
|
---|
241 | : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, ut, 0, umax))
|
---|
242 | # else
|
---|
243 | # define _GL_INT_OP_WRAPV_SMALLISH(a,b,r,op,overflow,st,smin,smax,ut,umax) \
|
---|
244 | (overflow (a, b, smin, smax) \
|
---|
245 | ? (overflow (a, b, 0, umax) \
|
---|
246 | ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 1) \
|
---|
247 | : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) < 0) \
|
---|
248 | : (overflow (a, b, 0, umax) \
|
---|
249 | ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st)) >= 0 \
|
---|
250 | : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0)))
|
---|
251 | # endif
|
---|
252 |
|
---|
253 | # define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
|
---|
254 | (sizeof *(r) == sizeof (signed char) \
|
---|
255 | ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
|
---|
256 | signed char, SCHAR_MIN, SCHAR_MAX, \
|
---|
257 | unsigned char, UCHAR_MAX) \
|
---|
258 | : sizeof *(r) == sizeof (short int) \
|
---|
259 | ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \
|
---|
260 | short int, SHRT_MIN, SHRT_MAX, \
|
---|
261 | unsigned short int, USHRT_MAX) \
|
---|
262 | : sizeof *(r) == sizeof (int) \
|
---|
263 | ? (_GL_EXPR_SIGNED (*(r)) \
|
---|
264 | ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
265 | int, INT_MIN, INT_MAX) \
|
---|
266 | : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
|
---|
267 | unsigned int, 0, UINT_MAX)) \
|
---|
268 | : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
|
---|
269 | # ifdef LLONG_MAX
|
---|
270 | # define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
|
---|
271 | (sizeof *(r) == sizeof (long int) \
|
---|
272 | ? (_GL_EXPR_SIGNED (*(r)) \
|
---|
273 | ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
274 | long int, LONG_MIN, LONG_MAX) \
|
---|
275 | : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
276 | unsigned long int, 0, ULONG_MAX)) \
|
---|
277 | : (_GL_EXPR_SIGNED (*(r)) \
|
---|
278 | ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
|
---|
279 | long long int, LLONG_MIN, LLONG_MAX) \
|
---|
280 | : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
|
---|
281 | unsigned long long int, 0, ULLONG_MAX)))
|
---|
282 | # else
|
---|
283 | # define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
|
---|
284 | (_GL_EXPR_SIGNED (*(r)) \
|
---|
285 | ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
286 | long int, LONG_MIN, LONG_MAX) \
|
---|
287 | : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
|
---|
288 | unsigned long int, 0, ULONG_MAX))
|
---|
289 | # endif
|
---|
290 | #endif
|
---|
291 |
|
---|
292 | /* Store the low-order bits of A <op> B into *R, where the operation
|
---|
293 | is given by OP. Use the unsigned type UT for calculation to avoid
|
---|
294 | overflow problems. *R's type is T, with extrema TMIN and TMAX.
|
---|
295 | T can be any signed integer type other than char, bool, a
|
---|
296 | bit-precise integer type, or an enumeration type.
|
---|
297 | Return 1 if the result overflows. */
|
---|
298 | #define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
|
---|
299 | (overflow (a, b, tmin, tmax) \
|
---|
300 | ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
|
---|
301 | : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
|
---|
302 |
|
---|
303 | /* Return 1 if the integer expressions A - B and -A would overflow,
|
---|
304 | respectively. Arguments should not have side effects,
|
---|
305 | and can be any signed integer type other than char, bool, a
|
---|
306 | bit-precise integer type, or an enumeration type.
|
---|
307 | These macros are tuned for their last input argument being a constant. */
|
---|
308 |
|
---|
309 | #if _GL_HAS_BUILTIN_OVERFLOW_P
|
---|
310 | # define _GL_INT_NEGATE_OVERFLOW(a) \
|
---|
311 | __builtin_sub_overflow_p (0, a, (__typeof__ (- (a))) 0)
|
---|
312 | #else
|
---|
313 | # define _GL_INT_NEGATE_OVERFLOW(a) \
|
---|
314 | _GL_INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
|
---|
315 | #endif
|
---|
316 |
|
---|
317 | /* Return the low-order bits of A <op> B, where the operation is given
|
---|
318 | by OP. Use the unsigned type UT for calculation to avoid undefined
|
---|
319 | behavior on signed integer overflow, and convert the result to type T.
|
---|
320 | UT is at least as wide as T and is no narrower than unsigned int,
|
---|
321 | T is two's complement, and there is no padding or trap representations.
|
---|
322 | Assume that converting UT to T yields the low-order bits, as is
|
---|
323 | done in all known two's-complement C compilers. E.g., see:
|
---|
324 | https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html
|
---|
325 |
|
---|
326 | According to the C standard, converting UT to T yields an
|
---|
327 | implementation-defined result or signal for values outside T's
|
---|
328 | range. However, code that works around this theoretical problem
|
---|
329 | runs afoul of a compiler bug in Oracle Studio 12.3 x86. See:
|
---|
330 | https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html
|
---|
331 | As the compiler bug is real, don't try to work around the
|
---|
332 | theoretical problem. */
|
---|
333 |
|
---|
334 | #define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
|
---|
335 | ((t) ((ut) (a) op (ut) (b)))
|
---|
336 |
|
---|
337 | /* Return true if the numeric values A + B, A - B, A * B fall outside
|
---|
338 | the range TMIN..TMAX. Arguments should not have side effects
|
---|
339 | and can be any integer type other than char, bool,
|
---|
340 | a bit-precise integer type, or an enumeration type.
|
---|
341 | TMIN should be signed and nonpositive.
|
---|
342 | TMAX should be positive, and should be signed unless TMIN is zero. */
|
---|
343 | #define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \
|
---|
344 | ((b) < 0 \
|
---|
345 | ? (((tmin) \
|
---|
346 | ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \
|
---|
347 | && (a) < (tmin) - (b)) \
|
---|
348 | : (a) <= -1 - (b)) \
|
---|
349 | || ((_GL_EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \
|
---|
350 | : (a) < 0 \
|
---|
351 | ? (((tmin) \
|
---|
352 | ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \
|
---|
353 | && (b) < (tmin) - (a)) \
|
---|
354 | : (b) <= -1 - (a)) \
|
---|
355 | || ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \
|
---|
356 | && (tmax) < (a) + (b))) \
|
---|
357 | : (tmax) < (b) || (tmax) - (b) < (a))
|
---|
358 | #define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
|
---|
359 | (((a) < 0) == ((b) < 0) \
|
---|
360 | ? ((a) < (b) \
|
---|
361 | ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
|
---|
362 | : (tmax) < (a) - (b)) \
|
---|
363 | : (a) < 0 \
|
---|
364 | ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \
|
---|
365 | || (a) - (tmin) < (b)) \
|
---|
366 | : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
|
---|
367 | && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
|
---|
368 | && (tmax) <= -1 - (b)) \
|
---|
369 | || (tmax) + (b) < (a)))
|
---|
370 | #define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \
|
---|
371 | ((b) < 0 \
|
---|
372 | ? ((a) < 0 \
|
---|
373 | ? (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
|
---|
374 | ? (a) < (tmax) / (b) \
|
---|
375 | : ((_GL_INT_NEGATE_OVERFLOW (b) \
|
---|
376 | ? _GL_INT_CONVERT (b, tmax) >> (_GL_TYPE_WIDTH (+ (b)) - 1) \
|
---|
377 | : (tmax) / -(b)) \
|
---|
378 | <= -1 - (a))) \
|
---|
379 | : _GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \
|
---|
380 | ? (_GL_EXPR_SIGNED (a) \
|
---|
381 | ? 0 < (a) + (tmin) \
|
---|
382 | : 0 < (a) && -1 - (tmin) < (a) - 1) \
|
---|
383 | : (tmin) / (b) < (a)) \
|
---|
384 | : (b) == 0 \
|
---|
385 | ? 0 \
|
---|
386 | : ((a) < 0 \
|
---|
387 | ? (_GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \
|
---|
388 | ? (_GL_EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \
|
---|
389 | : (tmin) / (a) < (b)) \
|
---|
390 | : (tmax) / (b) < (a)))
|
---|
391 |
|
---|
392 | #endif /* _GL_INTPROPS_INTERNAL_H */
|
---|