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