diff options
author | Kristian Schuster <116557017+KriSchu@users.noreply.github.com> | 2023-02-19 23:49:18 +0100 |
---|---|---|
committer | Kristian Schuster <116557017+KriSchu@users.noreply.github.com> | 2023-02-19 23:49:18 +0100 |
commit | a0d42777217296c0a7bdb1e1be8d8f6de1b24dd7 (patch) | |
tree | 8effe94c57b2f9796ba36090b07551baa8f1e1cb /gl/intprops-internal.h | |
parent | ca3d59cd6918c9e2739e783b721d4c1122640fd3 (diff) | |
parent | c07206f2ccc2356aa74bc6813a94c2190017d44e (diff) | |
download | monitoring-plugins-a0d4277.tar.gz |
Merge remote-tracking branch 'origin/master' into feature_check_disk_add_ignore_missing_option
Diffstat (limited to 'gl/intprops-internal.h')
-rw-r--r-- | gl/intprops-internal.h | 392 |
1 files changed, 392 insertions, 0 deletions
diff --git a/gl/intprops-internal.h b/gl/intprops-internal.h new file mode 100644 index 00000000..0467a9ca --- /dev/null +++ b/gl/intprops-internal.h | |||
@@ -0,0 +1,392 @@ | |||
1 | /* intprops-internal.h -- properties of integer types not visible to users | ||
2 | |||
3 | Copyright (C) 2001-2023 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 */ | ||