Wireshark  4.3.0
The Wireshark network protocol analyzer
safe-math.h
1 /* Overflow-safe math functions
2  * Portable Snippets - https://github.com/nemequ/portable-snippets
3  * Created by Evan Nemerson <evan@nemerson.com>
4  *
5  * To the extent possible under law, the authors have waived all
6  * copyright and related or neighboring rights to this code. For
7  * details, see the Creative Commons Zero 1.0 Universal license at
8  * https://creativecommons.org/publicdomain/zero/1.0/
9  */
10 
11 #if !defined(PSNIP_SAFE_H)
12 #define PSNIP_SAFE_H
13 
14 #if !defined(PSNIP_SAFE_FORCE_PORTABLE)
15 # if defined(__has_builtin)
16 # if __has_builtin(__builtin_add_overflow) && !defined(__ibmxl__)
17 # define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
18 # endif
19 # elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER)
20 # define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW
21 # endif
22 # if defined(__has_include)
23 # if __has_include(<intsafe.h>)
24 # define PSNIP_SAFE_HAVE_INTSAFE_H
25 # endif
26 # elif defined(_WIN32)
27 # define PSNIP_SAFE_HAVE_INTSAFE_H
28 # endif
29 #endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */
30 
31 #if defined(__GNUC__)
32 # define PSNIP_SAFE_LIKELY(expr) __builtin_expect(!!(expr), 1)
33 # define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
34 #else
35 # define PSNIP_SAFE_LIKELY(expr) !!(expr)
36 # define PSNIP_SAFE_UNLIKELY(expr) !!(expr)
37 #endif /* defined(__GNUC__) */
38 
39 #if !defined(PSNIP_SAFE_STATIC_INLINE)
40 # if defined(__GNUC__)
41 # define PSNIP_SAFE__COMPILER_ATTRIBUTES __attribute__((__unused__))
42 # else
43 # define PSNIP_SAFE__COMPILER_ATTRIBUTES
44 # endif
45 
46 # if defined(HEDLEY_INLINE)
47 # define PSNIP_SAFE__INLINE HEDLEY_INLINE
48 # elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
49 # define PSNIP_SAFE__INLINE inline
50 # elif defined(__GNUC_STDC_INLINE__)
51 # define PSNIP_SAFE__INLINE __inline__
52 # elif defined(_MSC_VER) && _MSC_VER >= 1200
53 # define PSNIP_SAFE__INLINE __inline
54 # else
55 # define PSNIP_SAFE__INLINE
56 # endif
57 
58 # define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE
59 #endif
60 
61 #if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
62 # define psnip_safe_bool _Bool
63 #else
64 # define psnip_safe_bool int
65 #endif
66 
67 #if !defined(PSNIP_SAFE_NO_FIXED)
68 /* For maximum portability include the exact-int module from
69  portable snippets. */
70 # if \
71  !defined(psnip_int64_t) || !defined(psnip_uint64_t) || \
72  !defined(psnip_int32_t) || !defined(psnip_uint32_t) || \
73  !defined(psnip_int16_t) || !defined(psnip_uint16_t) || \
74  !defined(psnip_int8_t) || !defined(psnip_uint8_t)
75 # include <stdint.h>
76 # if !defined(psnip_int64_t)
77 # define psnip_int64_t int64_t
78 # endif
79 # if !defined(psnip_uint64_t)
80 # define psnip_uint64_t uint64_t
81 # endif
82 # if !defined(psnip_int32_t)
83 # define psnip_int32_t int32_t
84 # endif
85 # if !defined(psnip_uint32_t)
86 # define psnip_uint32_t uint32_t
87 # endif
88 # if !defined(psnip_int16_t)
89 # define psnip_int16_t int16_t
90 # endif
91 # if !defined(psnip_uint16_t)
92 # define psnip_uint16_t uint16_t
93 # endif
94 # if !defined(psnip_int8_t)
95 # define psnip_int8_t int8_t
96 # endif
97 # if !defined(psnip_uint8_t)
98 # define psnip_uint8_t uint8_t
99 # endif
100 # endif
101 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
102 #include <limits.h>
103 #include <stdlib.h>
104 
105 #if !defined(PSNIP_SAFE_SIZE_MAX)
106 # if defined(__SIZE_MAX__)
107 # define PSNIP_SAFE_SIZE_MAX __SIZE_MAX__
108 # elif defined(PSNIP_EXACT_INT_HAVE_STDINT)
109 # include <stdint.h>
110 # endif
111 #endif
112 
113 #if defined(PSNIP_SAFE_SIZE_MAX)
114 # define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX
115 #else
116 # define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0))
117 #endif
118 
119 #if defined(PSNIP_SAFE_HAVE_INTSAFE_H)
120 /* In VS 10, stdint.h and intsafe.h both define (U)INTN_MIN/MAX, which
121  triggers warning C4005 (level 1). */
122 # if defined(_MSC_VER) && (_MSC_VER == 1600)
123 # pragma warning(push)
124 # pragma warning(disable:4005)
125 # endif
126 # include <intsafe.h>
127 # if defined(_MSC_VER) && (_MSC_VER == 1600)
128 # pragma warning(pop)
129 # endif
130 #endif /* defined(PSNIP_SAFE_HAVE_INTSAFE_H) */
131 
132 /* If there is a type larger than the one we're concerned with it's
133  * likely much faster to simply promote the operands, perform the
134  * requested operation, verify that the result falls within the
135  * original type, then cast the result back to the original type. */
136 
137 #if !defined(PSNIP_SAFE_NO_PROMOTIONS)
138 
139 #define PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, op_name, op) \
140  PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
141  psnip_safe_larger_##name##_##op_name (T a, T b) { \
142  return ((psnip_safe_##name##_larger) a) op ((psnip_safe_##name##_larger) b); \
143  }
144 
145 #define PSNIP_SAFE_DEFINE_LARGER_UNARY_OP(T, name, op_name, op) \
146  PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \
147  psnip_safe_larger_##name##_##op_name (T value) { \
148  return (op ((psnip_safe_##name##_larger) value)); \
149  }
150 
151 #define PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(T, name) \
152  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
153  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
154  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
155  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
156  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) \
157  PSNIP_SAFE_DEFINE_LARGER_UNARY_OP (T, name, neg, -)
158 
159 #define PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(T, name) \
160  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \
161  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \
162  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \
163  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \
164  PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %)
165 
166 #define PSNIP_SAFE_IS_LARGER(ORIG_MAX, DEST_MAX) ((DEST_MAX / ORIG_MAX) >= ORIG_MAX)
167 
168 #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__SIZEOF_INT128__) && !defined(__ibmxl__)
169 #define PSNIP_SAFE_HAVE_128
170 typedef __int128 psnip_safe_int128_t;
171 typedef unsigned __int128 psnip_safe_uint128_t;
172 #endif /* defined(__GNUC__) */
173 
174 #if !defined(PSNIP_SAFE_NO_FIXED)
175 #define PSNIP_SAFE_HAVE_INT8_LARGER
176 #define PSNIP_SAFE_HAVE_UINT8_LARGER
177 typedef psnip_int16_t psnip_safe_int8_larger;
178 typedef psnip_uint16_t psnip_safe_uint8_larger;
179 
180 #define PSNIP_SAFE_HAVE_INT16_LARGER
181 typedef psnip_int32_t psnip_safe_int16_larger;
182 typedef psnip_uint32_t psnip_safe_uint16_larger;
183 
184 #define PSNIP_SAFE_HAVE_INT32_LARGER
185 typedef psnip_int64_t psnip_safe_int32_larger;
186 typedef psnip_uint64_t psnip_safe_uint32_larger;
187 
188 #if defined(PSNIP_SAFE_HAVE_128)
189 #define PSNIP_SAFE_HAVE_INT64_LARGER
190 typedef psnip_safe_int128_t psnip_safe_int64_larger;
191 typedef psnip_safe_uint128_t psnip_safe_uint64_larger;
192 #endif /* defined(PSNIP_SAFE_HAVE_128) */
193 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
194 
195 #define PSNIP_SAFE_HAVE_LARGER_SCHAR
196 #if PSNIP_SAFE_IS_LARGER(SCHAR_MAX, SHRT_MAX)
197 typedef short psnip_safe_schar_larger;
198 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX)
199 typedef int psnip_safe_schar_larger;
200 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX)
201 typedef long psnip_safe_schar_larger;
202 #elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX)
203 typedef long long psnip_safe_schar_larger;
204 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff)
205 typedef psnip_int16_t psnip_safe_schar_larger;
206 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL)
207 typedef psnip_int32_t psnip_safe_schar_larger;
208 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL)
209 typedef psnip_int64_t psnip_safe_schar_larger;
210 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL)
211 typedef psnip_safe_int128_t psnip_safe_schar_larger;
212 #else
213 #undef PSNIP_SAFE_HAVE_LARGER_SCHAR
214 #endif
215 
216 #define PSNIP_SAFE_HAVE_LARGER_UCHAR
217 #if PSNIP_SAFE_IS_LARGER(UCHAR_MAX, USHRT_MAX)
218 typedef unsigned short psnip_safe_uchar_larger;
219 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX)
220 typedef unsigned int psnip_safe_uchar_larger;
221 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX)
222 typedef unsigned long psnip_safe_uchar_larger;
223 #elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX)
224 typedef unsigned long long psnip_safe_uchar_larger;
225 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU)
226 typedef psnip_uint16_t psnip_safe_uchar_larger;
227 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL)
228 typedef psnip_uint32_t psnip_safe_uchar_larger;
229 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL)
230 typedef psnip_uint64_t psnip_safe_uchar_larger;
231 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL)
232 typedef psnip_safe_uint128_t psnip_safe_uchar_larger;
233 #else
234 #undef PSNIP_SAFE_HAVE_LARGER_UCHAR
235 #endif
236 
237 #if CHAR_MIN == 0 && defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
238 #define PSNIP_SAFE_HAVE_LARGER_CHAR
239 typedef psnip_safe_uchar_larger psnip_safe_char_larger;
240 #elif CHAR_MIN < 0 && defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
241 #define PSNIP_SAFE_HAVE_LARGER_CHAR
242 typedef psnip_safe_schar_larger psnip_safe_char_larger;
243 #endif
244 
245 #define PSNIP_SAFE_HAVE_LARGER_SHRT
246 #if PSNIP_SAFE_IS_LARGER(SHRT_MAX, INT_MAX)
247 typedef int psnip_safe_short_larger;
248 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX)
249 typedef long psnip_safe_short_larger;
250 #elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX)
251 typedef long long psnip_safe_short_larger;
252 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff)
253 typedef psnip_int16_t psnip_safe_short_larger;
254 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL)
255 typedef psnip_int32_t psnip_safe_short_larger;
256 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL)
257 typedef psnip_int64_t psnip_safe_short_larger;
258 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL)
259 typedef psnip_safe_int128_t psnip_safe_short_larger;
260 #else
261 #undef PSNIP_SAFE_HAVE_LARGER_SHRT
262 #endif
263 
264 #define PSNIP_SAFE_HAVE_LARGER_USHRT
265 #if PSNIP_SAFE_IS_LARGER(USHRT_MAX, UINT_MAX)
266 typedef unsigned int psnip_safe_ushort_larger;
267 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX)
268 typedef unsigned long psnip_safe_ushort_larger;
269 #elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX)
270 typedef unsigned long long psnip_safe_ushort_larger;
271 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff)
272 typedef psnip_uint16_t psnip_safe_ushort_larger;
273 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL)
274 typedef psnip_uint32_t psnip_safe_ushort_larger;
275 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL)
276 typedef psnip_uint64_t psnip_safe_ushort_larger;
277 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL)
278 typedef psnip_safe_uint128_t psnip_safe_ushort_larger;
279 #else
280 #undef PSNIP_SAFE_HAVE_LARGER_USHRT
281 #endif
282 
283 #define PSNIP_SAFE_HAVE_LARGER_INT
284 #if PSNIP_SAFE_IS_LARGER(INT_MAX, LONG_MAX)
285 typedef long psnip_safe_int_larger;
286 #elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX)
287 typedef long long psnip_safe_int_larger;
288 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff)
289 typedef psnip_int16_t psnip_safe_int_larger;
290 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL)
291 typedef psnip_int32_t psnip_safe_int_larger;
292 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL)
293 typedef psnip_int64_t psnip_safe_int_larger;
294 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL)
295 typedef psnip_safe_int128_t psnip_safe_int_larger;
296 #else
297 #undef PSNIP_SAFE_HAVE_LARGER_INT
298 #endif
299 
300 #define PSNIP_SAFE_HAVE_LARGER_UINT
301 #if PSNIP_SAFE_IS_LARGER(UINT_MAX, ULONG_MAX)
302 typedef unsigned long psnip_safe_uint_larger;
303 #elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX)
304 typedef unsigned long long psnip_safe_uint_larger;
305 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff)
306 typedef psnip_uint16_t psnip_safe_uint_larger;
307 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL)
308 typedef psnip_uint32_t psnip_safe_uint_larger;
309 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL)
310 typedef psnip_uint64_t psnip_safe_uint_larger;
311 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL)
312 typedef psnip_safe_uint128_t psnip_safe_uint_larger;
313 #else
314 #undef PSNIP_SAFE_HAVE_LARGER_UINT
315 #endif
316 
317 #define PSNIP_SAFE_HAVE_LARGER_LONG
318 #if PSNIP_SAFE_IS_LARGER(LONG_MAX, LLONG_MAX)
319 typedef long long psnip_safe_long_larger;
320 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff)
321 typedef psnip_int16_t psnip_safe_long_larger;
322 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL)
323 typedef psnip_int32_t psnip_safe_long_larger;
324 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL)
325 typedef psnip_int64_t psnip_safe_long_larger;
326 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL)
327 typedef psnip_safe_int128_t psnip_safe_long_larger;
328 #else
329 #undef PSNIP_SAFE_HAVE_LARGER_LONG
330 #endif
331 
332 #define PSNIP_SAFE_HAVE_LARGER_ULONG
333 #if PSNIP_SAFE_IS_LARGER(ULONG_MAX, ULLONG_MAX)
334 typedef unsigned long long psnip_safe_ulong_larger;
335 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff)
336 typedef psnip_uint16_t psnip_safe_ulong_larger;
337 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL)
338 typedef psnip_uint32_t psnip_safe_ulong_larger;
339 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL)
340 typedef psnip_uint64_t psnip_safe_ulong_larger;
341 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL)
342 typedef psnip_safe_uint128_t psnip_safe_ulong_larger;
343 #else
344 #undef PSNIP_SAFE_HAVE_LARGER_ULONG
345 #endif
346 
347 #define PSNIP_SAFE_HAVE_LARGER_LLONG
348 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fff)
349 typedef psnip_int16_t psnip_safe_llong_larger;
350 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL)
351 typedef psnip_int32_t psnip_safe_llong_larger;
352 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL)
353 typedef psnip_int64_t psnip_safe_llong_larger;
354 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL)
355 typedef psnip_safe_int128_t psnip_safe_llong_larger;
356 #else
357 #undef PSNIP_SAFE_HAVE_LARGER_LLONG
358 #endif
359 
360 #define PSNIP_SAFE_HAVE_LARGER_ULLONG
361 #if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffff)
362 typedef psnip_uint16_t psnip_safe_ullong_larger;
363 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL)
364 typedef psnip_uint32_t psnip_safe_ullong_larger;
365 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL)
366 typedef psnip_uint64_t psnip_safe_ullong_larger;
367 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL)
368 typedef psnip_safe_uint128_t psnip_safe_ullong_larger;
369 #else
370 #undef PSNIP_SAFE_HAVE_LARGER_ULLONG
371 #endif
372 
373 #if defined(PSNIP_SAFE_SIZE_MAX)
374 #define PSNIP_SAFE_HAVE_LARGER_SIZE
375 #if PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, USHRT_MAX)
376 typedef unsigned short psnip_safe_size_larger;
377 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX)
378 typedef unsigned int psnip_safe_size_larger;
379 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX)
380 typedef unsigned long psnip_safe_size_larger;
381 #elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX)
382 typedef unsigned long long psnip_safe_size_larger;
383 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff)
384 typedef psnip_uint16_t psnip_safe_size_larger;
385 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL)
386 typedef psnip_uint32_t psnip_safe_size_larger;
387 #elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL)
388 typedef psnip_uint64_t psnip_safe_size_larger;
389 #elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL)
390 typedef psnip_safe_uint128_t psnip_safe_size_larger;
391 #else
392 #undef PSNIP_SAFE_HAVE_LARGER_SIZE
393 #endif
394 #endif
395 
396 #if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
397 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar)
398 #endif
399 
400 #if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
401 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar)
402 #endif
403 
404 #if defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
405 #if CHAR_MIN == 0
406 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char)
407 #else
408 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char)
409 #endif
410 #endif
411 
412 #if defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
413 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short)
414 #endif
415 
416 #if defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
417 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort)
418 #endif
419 
420 #if defined(PSNIP_SAFE_HAVE_LARGER_INT)
421 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int)
422 #endif
423 
424 #if defined(PSNIP_SAFE_HAVE_LARGER_UINT)
425 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint)
426 #endif
427 
428 #if defined(PSNIP_SAFE_HAVE_LARGER_LONG)
429 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long)
430 #endif
431 
432 #if defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
433 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong)
434 #endif
435 
436 #if defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
437 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong)
438 #endif
439 
440 #if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
441 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong)
442 #endif
443 
444 #if defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
445 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size)
446 #endif
447 
448 #if !defined(PSNIP_SAFE_NO_FIXED)
449 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t, int8)
450 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t, uint8)
451 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t, int16)
452 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t, uint16)
453 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t, int32)
454 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t, uint32)
455 #if defined(PSNIP_SAFE_HAVE_128)
456 PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t, int64)
457 PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint64_t, uint64)
458 #endif
459 #endif
460 
461 #endif /* !defined(PSNIP_SAFE_NO_PROMOTIONS) */
462 
463 #define PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(T, name, op_name) \
464  PSNIP_SAFE__FUNCTION psnip_safe_bool \
465  psnip_safe_##name##_##op_name(T* res, T a, T b) { \
466  return !__builtin_##op_name##_overflow(a, b, res); \
467  }
468 
469 #define PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(T, name, op_name, min, max) \
470  PSNIP_SAFE__FUNCTION psnip_safe_bool \
471  psnip_safe_##name##_##op_name(T* res, T a, T b) { \
472  const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
473  *res = (T) r; \
474  return (r >= min) && (r <= max); \
475  }
476 
477 #define PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(T, name, op_name, max) \
478  PSNIP_SAFE__FUNCTION psnip_safe_bool \
479  psnip_safe_##name##_##op_name(T* res, T a, T b) { \
480  const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \
481  *res = (T) r; \
482  return (r <= max); \
483  }
484 
485 #define PSNIP_SAFE_DEFINE_SIGNED_ADD(T, name, min, max) \
486  PSNIP_SAFE__FUNCTION psnip_safe_bool \
487  psnip_safe_##name##_add (T* res, T a, T b) { \
488  psnip_safe_bool r = !( ((b > 0) && (a > (max - b))) || \
489  ((b < 0) && (a < (min - b))) ); \
490  if(PSNIP_SAFE_LIKELY(r)) \
491  *res = a + b; \
492  return r; \
493  }
494 
495 #define PSNIP_SAFE_DEFINE_UNSIGNED_ADD(T, name, max) \
496  PSNIP_SAFE__FUNCTION psnip_safe_bool \
497  psnip_safe_##name##_add (T* res, T a, T b) { \
498  *res = (T) (a + b); \
499  return !PSNIP_SAFE_UNLIKELY((b > 0) && (a > (max - b))); \
500  }
501 
502 #define PSNIP_SAFE_DEFINE_SIGNED_SUB(T, name, min, max) \
503  PSNIP_SAFE__FUNCTION psnip_safe_bool \
504  psnip_safe_##name##_sub (T* res, T a, T b) { \
505  psnip_safe_bool r = !((b > 0 && a < (min + b)) || \
506  (b < 0 && a > (max + b))); \
507  if(PSNIP_SAFE_LIKELY(r)) \
508  *res = a - b; \
509  return r; \
510  }
511 
512 #define PSNIP_SAFE_DEFINE_UNSIGNED_SUB(T, name, max) \
513  PSNIP_SAFE__FUNCTION psnip_safe_bool \
514  psnip_safe_##name##_sub (T* res, T a, T b) { \
515  *res = a - b; \
516  return !PSNIP_SAFE_UNLIKELY(b > a); \
517  }
518 
519 #define PSNIP_SAFE_DEFINE_SIGNED_MUL(T, name, min, max) \
520  PSNIP_SAFE__FUNCTION psnip_safe_bool \
521  psnip_safe_##name##_mul (T* res, T a, T b) { \
522  psnip_safe_bool r = 1; \
523  if (a > 0) { \
524  if (b > 0) { \
525  if (a > (max / b)) { \
526  r = 0; \
527  } \
528  } else { \
529  if (b < (min / a)) { \
530  r = 0; \
531  } \
532  } \
533  } else { \
534  if (b > 0) { \
535  if (a < (min / b)) { \
536  r = 0; \
537  } \
538  } else { \
539  if ( (a != 0) && (b < (max / a))) { \
540  r = 0; \
541  } \
542  } \
543  } \
544  if(PSNIP_SAFE_LIKELY(r)) \
545  *res = a * b; \
546  return r; \
547  }
548 
549 #define PSNIP_SAFE_DEFINE_UNSIGNED_MUL(T, name, max) \
550  PSNIP_SAFE__FUNCTION psnip_safe_bool \
551  psnip_safe_##name##_mul (T* res, T a, T b) { \
552  *res = (T) (a * b); \
553  return !PSNIP_SAFE_UNLIKELY((a > 0) && (b > 0) && (a > (max / b))); \
554  }
555 
556 #define PSNIP_SAFE_DEFINE_SIGNED_DIV(T, name, min, max) \
557  PSNIP_SAFE__FUNCTION psnip_safe_bool \
558  psnip_safe_##name##_div (T* res, T a, T b) { \
559  if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
560  *res = 0; \
561  return 0; \
562  } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
563  *res = min; \
564  return 0; \
565  } else { \
566  *res = (T) (a / b); \
567  return 1; \
568  } \
569  }
570 
571 #define PSNIP_SAFE_DEFINE_UNSIGNED_DIV(T, name, max) \
572  PSNIP_SAFE__FUNCTION psnip_safe_bool \
573  psnip_safe_##name##_div (T* res, T a, T b) { \
574  if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
575  *res = 0; \
576  return 0; \
577  } else { \
578  *res = a / b; \
579  return 1; \
580  } \
581  }
582 
583 #define PSNIP_SAFE_DEFINE_SIGNED_MOD(T, name, min, max) \
584  PSNIP_SAFE__FUNCTION psnip_safe_bool \
585  psnip_safe_##name##_mod (T* res, T a, T b) { \
586  if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
587  *res = 0; \
588  return 0; \
589  } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \
590  *res = min; \
591  return 0; \
592  } else { \
593  *res = (T) (a % b); \
594  return 1; \
595  } \
596  }
597 
598 #define PSNIP_SAFE_DEFINE_UNSIGNED_MOD(T, name, max) \
599  PSNIP_SAFE__FUNCTION psnip_safe_bool \
600  psnip_safe_##name##_mod (T* res, T a, T b) { \
601  if (PSNIP_SAFE_UNLIKELY(b == 0)) { \
602  *res = 0; \
603  return 0; \
604  } else { \
605  *res = a % b; \
606  return 1; \
607  } \
608  }
609 
610 #define PSNIP_SAFE_DEFINE_SIGNED_NEG(T, name, min, max) \
611  PSNIP_SAFE__FUNCTION psnip_safe_bool \
612  psnip_safe_##name##_neg (T* res, T value) { \
613  psnip_safe_bool r = value != min; \
614  *res = PSNIP_SAFE_LIKELY(r) ? -value : max; \
615  return r; \
616  }
617 
618 #define PSNIP_SAFE_DEFINE_INTSAFE(T, name, op, isf) \
619  PSNIP_SAFE__FUNCTION psnip_safe_bool \
620  psnip_safe_##name##_##op (T* res, T a, T b) { \
621  return isf(a, b, res) == S_OK; \
622  }
623 
624 #if CHAR_MIN == 0
625 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
626 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
627 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
628 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
629 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
630 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add, CHAR_MAX)
631 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub, CHAR_MAX)
632 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul, CHAR_MAX)
633 #else
634 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX)
635 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX)
636 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX)
637 #endif
638 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX)
639 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX)
640 #else /* CHAR_MIN != 0 */
641 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
642 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
643 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
644 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
645 #elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
646 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add, CHAR_MIN, CHAR_MAX)
647 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub, CHAR_MIN, CHAR_MAX)
648 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul, CHAR_MIN, CHAR_MAX)
649 #else
650 PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN, CHAR_MAX)
651 PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN, CHAR_MAX)
652 PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN, CHAR_MAX)
653 #endif
654 PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN, CHAR_MAX)
655 PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN, CHAR_MAX)
656 PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN, CHAR_MAX)
657 #endif
658 
659 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
660 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, add)
661 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, sub)
662 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, mul)
663 #elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
664 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, add, SCHAR_MIN, SCHAR_MAX)
665 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, sub, SCHAR_MIN, SCHAR_MAX)
666 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, mul, SCHAR_MIN, SCHAR_MAX)
667 #else
668 PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
669 PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar, SCHAR_MIN, SCHAR_MAX)
670 PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar, SCHAR_MIN, SCHAR_MAX)
671 #endif
672 PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar, SCHAR_MIN, SCHAR_MAX)
673 PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
674 PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar, SCHAR_MIN, SCHAR_MAX)
675 
676 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
677 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, add)
678 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, sub)
679 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, mul)
680 #elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
681 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, add, UCHAR_MAX)
682 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, sub, UCHAR_MAX)
683 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, mul, UCHAR_MAX)
684 #else
685 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar, UCHAR_MAX)
686 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar, UCHAR_MAX)
687 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar, UCHAR_MAX)
688 #endif
689 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar, UCHAR_MAX)
690 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar, UCHAR_MAX)
691 
692 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
693 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add)
694 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub)
695 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul)
696 #elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
697 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add, SHRT_MIN, SHRT_MAX)
698 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub, SHRT_MIN, SHRT_MAX)
699 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul, SHRT_MIN, SHRT_MAX)
700 #else
701 PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN, SHRT_MAX)
702 PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN, SHRT_MAX)
703 PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN, SHRT_MAX)
704 #endif
705 PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN, SHRT_MAX)
706 PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN, SHRT_MAX)
707 PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN, SHRT_MAX)
708 
709 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
710 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, add)
711 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, sub)
712 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, mul)
713 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
714 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, add, UShortAdd)
715 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, sub, UShortSub)
716 PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, mul, UShortMult)
717 #elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
718 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, add, USHRT_MAX)
719 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, sub, USHRT_MAX)
720 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, mul, USHRT_MAX)
721 #else
722 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort, USHRT_MAX)
723 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort, USHRT_MAX)
724 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort, USHRT_MAX)
725 #endif
726 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort, USHRT_MAX)
727 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort, USHRT_MAX)
728 
729 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
730 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add)
731 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub)
732 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul)
733 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT)
734 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add, INT_MIN, INT_MAX)
735 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub, INT_MIN, INT_MAX)
736 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul, INT_MIN, INT_MAX)
737 #else
738 PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN, INT_MAX)
739 PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN, INT_MAX)
740 PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN, INT_MAX)
741 #endif
742 PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN, INT_MAX)
743 PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN, INT_MAX)
744 PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN, INT_MAX)
745 
746 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
747 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, add)
748 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, sub)
749 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, mul)
750 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
751 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, add, UIntAdd)
752 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, sub, UIntSub)
753 PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, mul, UIntMult)
754 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT)
755 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, add, UINT_MAX)
756 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, sub, UINT_MAX)
757 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, mul, UINT_MAX)
758 #else
759 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint, UINT_MAX)
760 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint, UINT_MAX)
761 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint, UINT_MAX)
762 #endif
763 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint, UINT_MAX)
764 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint, UINT_MAX)
765 
766 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
767 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add)
768 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub)
769 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul)
770 #elif defined(PSNIP_SAFE_HAVE_LARGER_LONG)
771 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add, LONG_MIN, LONG_MAX)
772 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub, LONG_MIN, LONG_MAX)
773 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul, LONG_MIN, LONG_MAX)
774 #else
775 PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN, LONG_MAX)
776 PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN, LONG_MAX)
777 PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN, LONG_MAX)
778 #endif
779 PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN, LONG_MAX)
780 PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN, LONG_MAX)
781 PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN, LONG_MAX)
782 
783 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
784 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, add)
785 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, sub)
786 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, mul)
787 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
788 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, add, ULongAdd)
789 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, sub, ULongSub)
790 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, mul, ULongMult)
791 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
792 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, add, ULONG_MAX)
793 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, sub, ULONG_MAX)
794 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, mul, ULONG_MAX)
795 #else
796 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong, ULONG_MAX)
797 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong, ULONG_MAX)
798 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong, ULONG_MAX)
799 #endif
800 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong, ULONG_MAX)
801 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong, ULONG_MAX)
802 
803 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
804 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, add)
805 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, sub)
806 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, mul)
807 #elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
808 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, add, LLONG_MIN, LLONG_MAX)
809 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, sub, LLONG_MIN, LLONG_MAX)
810 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, mul, LLONG_MIN, LLONG_MAX)
811 #else
812 PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong, LLONG_MIN, LLONG_MAX)
813 PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong, LLONG_MIN, LLONG_MAX)
814 PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong, LLONG_MIN, LLONG_MAX)
815 #endif
816 PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong, LLONG_MIN, LLONG_MAX)
817 PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong, LLONG_MIN, LLONG_MAX)
818 PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong, LLONG_MIN, LLONG_MAX)
819 
820 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
821 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, add)
822 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, sub)
823 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, mul)
824 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
825 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, add, ULongLongAdd)
826 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, sub, ULongLongSub)
827 PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, mul, ULongLongMult)
828 #elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
829 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, add, ULLONG_MAX)
830 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, sub, ULLONG_MAX)
831 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, mul, ULLONG_MAX)
832 #else
833 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong, ULLONG_MAX)
834 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong, ULLONG_MAX)
835 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong, ULLONG_MAX)
836 #endif
837 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong, ULLONG_MAX)
838 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong, ULLONG_MAX)
839 
840 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
841 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, add)
842 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, sub)
843 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, mul)
844 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
845 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, add, SizeTAdd)
846 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, sub, SizeTSub)
847 PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, mul, SizeTMult)
848 #elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
849 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, add, PSNIP_SAFE__SIZE_MAX_RT)
850 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, sub, PSNIP_SAFE__SIZE_MAX_RT)
851 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, mul, PSNIP_SAFE__SIZE_MAX_RT)
852 #else
853 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
854 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
855 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
856 #endif
857 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
858 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
859 
860 #if !defined(PSNIP_SAFE_NO_FIXED)
861 
862 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
863 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, add)
864 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, sub)
865 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, mul)
866 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT8)
867 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, add, (-0x7fLL-1), 0x7f)
868 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, sub, (-0x7fLL-1), 0x7f)
869 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, mul, (-0x7fLL-1), 0x7f)
870 #else
871 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
872 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
873 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
874 #endif
875 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
876 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
877 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
878 
879 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
880 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, add)
881 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, sub)
882 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, mul)
883 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8)
884 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, add, 0xff)
885 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, sub, 0xff)
886 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, mul, 0xff)
887 #else
888 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t, uint8, 0xff)
889 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t, uint8, 0xff)
890 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t, uint8, 0xff)
891 #endif
892 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t, uint8, 0xff)
893 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t, uint8, 0xff)
894 
895 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
896 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, add)
897 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, sub)
898 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, mul)
899 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT16)
900 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, add, (-32767-1), 0x7fff)
901 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, sub, (-32767-1), 0x7fff)
902 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, mul, (-32767-1), 0x7fff)
903 #else
904 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t, int16, (-32767-1), 0x7fff)
905 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t, int16, (-32767-1), 0x7fff)
906 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t, int16, (-32767-1), 0x7fff)
907 #endif
908 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t, int16, (-32767-1), 0x7fff)
909 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t, int16, (-32767-1), 0x7fff)
910 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t, int16, (-32767-1), 0x7fff)
911 
912 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
913 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, add)
914 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, sub)
915 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, mul)
916 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
917 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, add, UShortAdd)
918 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, sub, UShortSub)
919 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, mul, UShortMult)
920 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16)
921 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, add, 0xffff)
922 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, sub, 0xffff)
923 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, mul, 0xffff)
924 #else
925 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t, uint16, 0xffff)
926 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t, uint16, 0xffff)
927 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t, uint16, 0xffff)
928 #endif
929 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t, uint16, 0xffff)
930 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t, uint16, 0xffff)
931 
932 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
933 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, add)
934 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, sub)
935 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, mul)
936 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT32)
937 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, add, (-0x7fffffffLL-1), 0x7fffffffLL)
938 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, sub, (-0x7fffffffLL-1), 0x7fffffffLL)
939 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, mul, (-0x7fffffffLL-1), 0x7fffffffLL)
940 #else
941 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
942 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
943 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
944 #endif
945 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
946 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
947 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
948 
949 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
950 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, add)
951 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, sub)
952 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, mul)
953 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
954 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, add, UIntAdd)
955 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, sub, UIntSub)
956 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, mul, UIntMult)
957 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32)
958 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, add, 0xffffffffUL)
959 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, sub, 0xffffffffUL)
960 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, mul, 0xffffffffUL)
961 #else
962 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t, uint32, 0xffffffffUL)
963 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t, uint32, 0xffffffffUL)
964 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t, uint32, 0xffffffffUL)
965 #endif
966 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t, uint32, 0xffffffffUL)
967 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t, uint32, 0xffffffffUL)
968 
969 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
970 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, add)
971 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, sub)
972 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, mul)
973 #elif defined(PSNIP_SAFE_HAVE_LARGER_INT64)
974 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, add, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
975 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, sub, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
976 PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, mul, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
977 #else
978 PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
979 PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
980 PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
981 #endif
982 PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
983 PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
984 PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
985 
986 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
987 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, add)
988 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, sub)
989 PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, mul)
990 #elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
991 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, add, ULongLongAdd)
992 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, sub, ULongLongSub)
993 PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, mul, ULongLongMult)
994 #elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64)
995 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, add, 0xffffffffffffffffULL)
996 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, sub, 0xffffffffffffffffULL)
997 PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, mul, 0xffffffffffffffffULL)
998 #else
999 PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1000 PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1001 PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1002 #endif
1003 PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1004 PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1005 
1006 #endif /* !defined(PSNIP_SAFE_NO_FIXED) */
1007 
1008 #define PSNIP_SAFE_C11_GENERIC_SELECTION(res, op) \
1009  _Generic((*res), \
1010  char: psnip_safe_char_##op, \
1011  unsigned char: psnip_safe_uchar_##op, \
1012  short: psnip_safe_short_##op, \
1013  unsigned short: psnip_safe_ushort_##op, \
1014  int: psnip_safe_int_##op, \
1015  unsigned int: psnip_safe_uint_##op, \
1016  long: psnip_safe_long_##op, \
1017  unsigned long: psnip_safe_ulong_##op, \
1018  long long: psnip_safe_llong_##op, \
1019  unsigned long long: psnip_safe_ullong_##op)
1020 
1021 #define PSNIP_SAFE_C11_GENERIC_BINARY_OP(op, res, a, b) \
1022  PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, a, b)
1023 #define PSNIP_SAFE_C11_GENERIC_UNARY_OP(op, res, v) \
1024  PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, v)
1025 
1026 #if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
1027 #define psnip_safe_add(res, a, b) !__builtin_add_overflow(a, b, res)
1028 #define psnip_safe_sub(res, a, b) !__builtin_sub_overflow(a, b, res)
1029 #define psnip_safe_mul(res, a, b) !__builtin_mul_overflow(a, b, res)
1030 #define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b)
1031 #define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b)
1032 #define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1033 
1034 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
1035 /* The are no fixed-length or size selections because they cause an
1036  * error about _Generic specifying two compatible types. Hopefully
1037  * this doesn't cause problems on exotic platforms, but if it does
1038  * please let me know and I'll try to figure something out. */
1039 
1040 #define psnip_safe_add(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(add, res, a, b)
1041 #define psnip_safe_sub(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(sub, res, a, b)
1042 #define psnip_safe_mul(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mul, res, a, b)
1043 #define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b)
1044 #define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b)
1045 #define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v)
1046 #endif
1047 
1048 #include <setjmp.h>
1049 
1050 #define ws_safe_op_jmp(op, res, a, b, env) \
1051  do { \
1052  if(!psnip_safe_##op(res, a, b)) { \
1053  longjmp(env, 1); \
1054  } \
1055  } while (0)
1056 
1057 #define ws_safe_add_jmp(res, a, b, env) ws_safe_op_jmp(add, res, a, b, env)
1058 #define ws_safe_sub_jmp(res, a, b, env) ws_safe_op_jmp(sub, res, a, b, env)
1059 #define ws_safe_mul_jmp(res, a, b, env) ws_safe_op_jmp(mul, res, a, b, env)
1060 #define ws_safe_div_jmp(res, a, b, env) ws_safe_op_jmp(div, res, a, b, env)
1061 #define ws_safe_mod_jmp(res, a, b, env) ws_safe_op_jmp(mod, res, a, b, env)
1062 #define ws_safe_neg_jmp(res, a, b, env) ws_safe_op_jmp(neg, res, a, b, env)
1063 
1064 #endif /* !defined(PSNIP_SAFE_H) */