Wireshark 4.5.0
The Wireshark network protocol analyzer
Loading...
Searching...
No Matches
safe-math.h
1/* Overflow-safe math functions
2 * Portable Snippets - https://github.com/nemequ/portable-snippets
3 * Created by Evan Nemerson <[email protected]>
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
170typedef __int128 psnip_safe_int128_t;
171typedef 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
177typedef psnip_int16_t psnip_safe_int8_larger;
178typedef psnip_uint16_t psnip_safe_uint8_larger;
179
180#define PSNIP_SAFE_HAVE_INT16_LARGER
181typedef psnip_int32_t psnip_safe_int16_larger;
182typedef psnip_uint32_t psnip_safe_uint16_larger;
183
184#define PSNIP_SAFE_HAVE_INT32_LARGER
185typedef psnip_int64_t psnip_safe_int32_larger;
186typedef psnip_uint64_t psnip_safe_uint32_larger;
187
188#if defined(PSNIP_SAFE_HAVE_128)
189#define PSNIP_SAFE_HAVE_INT64_LARGER
190typedef psnip_safe_int128_t psnip_safe_int64_larger;
191typedef 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)
197typedef short psnip_safe_schar_larger;
198#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX)
199typedef int psnip_safe_schar_larger;
200#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX)
201typedef long psnip_safe_schar_larger;
202#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX)
203typedef long long psnip_safe_schar_larger;
204#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff)
205typedef psnip_int16_t psnip_safe_schar_larger;
206#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL)
207typedef psnip_int32_t psnip_safe_schar_larger;
208#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL)
209typedef psnip_int64_t psnip_safe_schar_larger;
210#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL)
211typedef 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)
218typedef unsigned short psnip_safe_uchar_larger;
219#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX)
220typedef unsigned int psnip_safe_uchar_larger;
221#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX)
222typedef unsigned long psnip_safe_uchar_larger;
223#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX)
224typedef unsigned long long psnip_safe_uchar_larger;
225#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU)
226typedef psnip_uint16_t psnip_safe_uchar_larger;
227#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL)
228typedef psnip_uint32_t psnip_safe_uchar_larger;
229#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL)
230typedef psnip_uint64_t psnip_safe_uchar_larger;
231#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL)
232typedef 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
239typedef 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
242typedef 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)
247typedef int psnip_safe_short_larger;
248#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX)
249typedef long psnip_safe_short_larger;
250#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX)
251typedef long long psnip_safe_short_larger;
252#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff)
253typedef psnip_int16_t psnip_safe_short_larger;
254#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL)
255typedef psnip_int32_t psnip_safe_short_larger;
256#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL)
257typedef psnip_int64_t psnip_safe_short_larger;
258#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL)
259typedef 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)
266typedef unsigned int psnip_safe_ushort_larger;
267#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX)
268typedef unsigned long psnip_safe_ushort_larger;
269#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX)
270typedef unsigned long long psnip_safe_ushort_larger;
271#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff)
272typedef psnip_uint16_t psnip_safe_ushort_larger;
273#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL)
274typedef psnip_uint32_t psnip_safe_ushort_larger;
275#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL)
276typedef psnip_uint64_t psnip_safe_ushort_larger;
277#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL)
278typedef 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)
285typedef long psnip_safe_int_larger;
286#elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX)
287typedef long long psnip_safe_int_larger;
288#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff)
289typedef psnip_int16_t psnip_safe_int_larger;
290#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL)
291typedef psnip_int32_t psnip_safe_int_larger;
292#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL)
293typedef psnip_int64_t psnip_safe_int_larger;
294#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL)
295typedef 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)
302typedef unsigned long psnip_safe_uint_larger;
303#elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX)
304typedef unsigned long long psnip_safe_uint_larger;
305#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff)
306typedef psnip_uint16_t psnip_safe_uint_larger;
307#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL)
308typedef psnip_uint32_t psnip_safe_uint_larger;
309#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL)
310typedef psnip_uint64_t psnip_safe_uint_larger;
311#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL)
312typedef 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)
319typedef long long psnip_safe_long_larger;
320#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff)
321typedef psnip_int16_t psnip_safe_long_larger;
322#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL)
323typedef psnip_int32_t psnip_safe_long_larger;
324#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL)
325typedef psnip_int64_t psnip_safe_long_larger;
326#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL)
327typedef 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)
334typedef unsigned long long psnip_safe_ulong_larger;
335#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff)
336typedef psnip_uint16_t psnip_safe_ulong_larger;
337#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL)
338typedef psnip_uint32_t psnip_safe_ulong_larger;
339#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL)
340typedef psnip_uint64_t psnip_safe_ulong_larger;
341#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL)
342typedef 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)
349typedef psnip_int16_t psnip_safe_llong_larger;
350#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL)
351typedef psnip_int32_t psnip_safe_llong_larger;
352#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL)
353typedef psnip_int64_t psnip_safe_llong_larger;
354#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL)
355typedef 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)
362typedef psnip_uint16_t psnip_safe_ullong_larger;
363#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL)
364typedef psnip_uint32_t psnip_safe_ullong_larger;
365#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL)
366typedef psnip_uint64_t psnip_safe_ullong_larger;
367#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL)
368typedef 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)
376typedef unsigned short psnip_safe_size_larger;
377#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX)
378typedef unsigned int psnip_safe_size_larger;
379#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX)
380typedef unsigned long psnip_safe_size_larger;
381#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX)
382typedef unsigned long long psnip_safe_size_larger;
383#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff)
384typedef psnip_uint16_t psnip_safe_size_larger;
385#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL)
386typedef psnip_uint32_t psnip_safe_size_larger;
387#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL)
388typedef psnip_uint64_t psnip_safe_size_larger;
389#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL)
390typedef 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)
397PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar)
398#endif
399
400#if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
401PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar)
402#endif
403
404#if defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
405#if CHAR_MIN == 0
406PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char)
407#else
408PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char)
409#endif
410#endif
411
412#if defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
413PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short)
414#endif
415
416#if defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
417PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort)
418#endif
419
420#if defined(PSNIP_SAFE_HAVE_LARGER_INT)
421PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int)
422#endif
423
424#if defined(PSNIP_SAFE_HAVE_LARGER_UINT)
425PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint)
426#endif
427
428#if defined(PSNIP_SAFE_HAVE_LARGER_LONG)
429PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long)
430#endif
431
432#if defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
433PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong)
434#endif
435
436#if defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
437PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong)
438#endif
439
440#if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
441PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong)
442#endif
443
444#if defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
445PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size)
446#endif
447
448#if !defined(PSNIP_SAFE_NO_FIXED)
449PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t, int8)
450PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t, uint8)
451PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t, int16)
452PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t, uint16)
453PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t, int32)
454PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t, uint32)
455#if defined(PSNIP_SAFE_HAVE_128)
456PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t, int64)
457PSNIP_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)
626PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
627PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
628PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
629#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
630PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add, CHAR_MAX)
631PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub, CHAR_MAX)
632PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul, CHAR_MAX)
633#else
634PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX)
635PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX)
636PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX)
637#endif
638PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX)
639PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX)
640#else /* CHAR_MIN != 0 */
641#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
642PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add)
643PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub)
644PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul)
645#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR)
646PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add, CHAR_MIN, CHAR_MAX)
647PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub, CHAR_MIN, CHAR_MAX)
648PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul, CHAR_MIN, CHAR_MAX)
649#else
650PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN, CHAR_MAX)
651PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN, CHAR_MAX)
652PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN, CHAR_MAX)
653#endif
654PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN, CHAR_MAX)
655PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN, CHAR_MAX)
656PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN, CHAR_MAX)
657#endif
658
659#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
660PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, add)
661PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, sub)
662PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, mul)
663#elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR)
664PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, add, SCHAR_MIN, SCHAR_MAX)
665PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, sub, SCHAR_MIN, SCHAR_MAX)
666PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, mul, SCHAR_MIN, SCHAR_MAX)
667#else
668PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
669PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar, SCHAR_MIN, SCHAR_MAX)
670PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar, SCHAR_MIN, SCHAR_MAX)
671#endif
672PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar, SCHAR_MIN, SCHAR_MAX)
673PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar, SCHAR_MIN, SCHAR_MAX)
674PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar, SCHAR_MIN, SCHAR_MAX)
675
676#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
677PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, add)
678PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, sub)
679PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, mul)
680#elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR)
681PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, add, UCHAR_MAX)
682PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, sub, UCHAR_MAX)
683PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, mul, UCHAR_MAX)
684#else
685PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar, UCHAR_MAX)
686PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar, UCHAR_MAX)
687PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar, UCHAR_MAX)
688#endif
689PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar, UCHAR_MAX)
690PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar, UCHAR_MAX)
691
692#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
693PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add)
694PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub)
695PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul)
696#elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT)
697PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add, SHRT_MIN, SHRT_MAX)
698PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub, SHRT_MIN, SHRT_MAX)
699PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul, SHRT_MIN, SHRT_MAX)
700#else
701PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN, SHRT_MAX)
702PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN, SHRT_MAX)
703PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN, SHRT_MAX)
704#endif
705PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN, SHRT_MAX)
706PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN, SHRT_MAX)
707PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN, SHRT_MAX)
708
709#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
710PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, add)
711PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, sub)
712PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, mul)
713#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
714PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, add, UShortAdd)
715PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, sub, UShortSub)
716PSNIP_SAFE_DEFINE_INTSAFE(unsigned short, ushort, mul, UShortMult)
717#elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT)
718PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, add, USHRT_MAX)
719PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, sub, USHRT_MAX)
720PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, mul, USHRT_MAX)
721#else
722PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort, USHRT_MAX)
723PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort, USHRT_MAX)
724PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort, USHRT_MAX)
725#endif
726PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort, USHRT_MAX)
727PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort, USHRT_MAX)
728
729#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
730PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add)
731PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub)
732PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul)
733#elif defined(PSNIP_SAFE_HAVE_LARGER_INT)
734PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add, INT_MIN, INT_MAX)
735PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub, INT_MIN, INT_MAX)
736PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul, INT_MIN, INT_MAX)
737#else
738PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN, INT_MAX)
739PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN, INT_MAX)
740PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN, INT_MAX)
741#endif
742PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN, INT_MAX)
743PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN, INT_MAX)
744PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN, INT_MAX)
745
746#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
747PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, add)
748PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, sub)
749PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, mul)
750#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
751PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, add, UIntAdd)
752PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, sub, UIntSub)
753PSNIP_SAFE_DEFINE_INTSAFE(unsigned int, uint, mul, UIntMult)
754#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT)
755PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, add, UINT_MAX)
756PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, sub, UINT_MAX)
757PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, mul, UINT_MAX)
758#else
759PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint, UINT_MAX)
760PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint, UINT_MAX)
761PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint, UINT_MAX)
762#endif
763PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint, UINT_MAX)
764PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint, UINT_MAX)
765
766#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
767PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add)
768PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub)
769PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul)
770#elif defined(PSNIP_SAFE_HAVE_LARGER_LONG)
771PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add, LONG_MIN, LONG_MAX)
772PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub, LONG_MIN, LONG_MAX)
773PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul, LONG_MIN, LONG_MAX)
774#else
775PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN, LONG_MAX)
776PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN, LONG_MAX)
777PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN, LONG_MAX)
778#endif
779PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN, LONG_MAX)
780PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN, LONG_MAX)
781PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN, LONG_MAX)
782
783#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
784PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, add)
785PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, sub)
786PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, mul)
787#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
788PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, add, ULongAdd)
789PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, sub, ULongSub)
790PSNIP_SAFE_DEFINE_INTSAFE(unsigned long, ulong, mul, ULongMult)
791#elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG)
792PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, add, ULONG_MAX)
793PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, sub, ULONG_MAX)
794PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, mul, ULONG_MAX)
795#else
796PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong, ULONG_MAX)
797PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong, ULONG_MAX)
798PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong, ULONG_MAX)
799#endif
800PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong, ULONG_MAX)
801PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong, ULONG_MAX)
802
803#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
804PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, add)
805PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, sub)
806PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, mul)
807#elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG)
808PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, add, LLONG_MIN, LLONG_MAX)
809PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, sub, LLONG_MIN, LLONG_MAX)
810PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, mul, LLONG_MIN, LLONG_MAX)
811#else
812PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong, LLONG_MIN, LLONG_MAX)
813PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong, LLONG_MIN, LLONG_MAX)
814PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong, LLONG_MIN, LLONG_MAX)
815#endif
816PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong, LLONG_MIN, LLONG_MAX)
817PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong, LLONG_MIN, LLONG_MAX)
818PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong, LLONG_MIN, LLONG_MAX)
819
820#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
821PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, add)
822PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, sub)
823PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, mul)
824#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
825PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, add, ULongLongAdd)
826PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, sub, ULongLongSub)
827PSNIP_SAFE_DEFINE_INTSAFE(unsigned long long, ullong, mul, ULongLongMult)
828#elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG)
829PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, add, ULLONG_MAX)
830PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, sub, ULLONG_MAX)
831PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, mul, ULLONG_MAX)
832#else
833PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong, ULLONG_MAX)
834PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong, ULLONG_MAX)
835PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong, ULLONG_MAX)
836#endif
837PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong, ULLONG_MAX)
838PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong, ULLONG_MAX)
839
840#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
841PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, add)
842PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, sub)
843PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, mul)
844#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H)
845PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, add, SizeTAdd)
846PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, sub, SizeTSub)
847PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, mul, SizeTMult)
848#elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE)
849PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, add, PSNIP_SAFE__SIZE_MAX_RT)
850PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, sub, PSNIP_SAFE__SIZE_MAX_RT)
851PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, mul, PSNIP_SAFE__SIZE_MAX_RT)
852#else
853PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
854PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
855PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
856#endif
857PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size, PSNIP_SAFE__SIZE_MAX_RT)
858PSNIP_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)
863PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, add)
864PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, sub)
865PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, mul)
866#elif defined(PSNIP_SAFE_HAVE_LARGER_INT8)
867PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, add, (-0x7fLL-1), 0x7f)
868PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, sub, (-0x7fLL-1), 0x7f)
869PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, mul, (-0x7fLL-1), 0x7f)
870#else
871PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
872PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
873PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
874#endif
875PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
876PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
877PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
878
879#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
880PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, add)
881PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, sub)
882PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, mul)
883#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8)
884PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, add, 0xff)
885PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, sub, 0xff)
886PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, mul, 0xff)
887#else
888PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t, uint8, 0xff)
889PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t, uint8, 0xff)
890PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t, uint8, 0xff)
891#endif
892PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t, uint8, 0xff)
893PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t, uint8, 0xff)
894
895#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
896PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, add)
897PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, sub)
898PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, mul)
899#elif defined(PSNIP_SAFE_HAVE_LARGER_INT16)
900PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, add, (-32767-1), 0x7fff)
901PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, sub, (-32767-1), 0x7fff)
902PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, mul, (-32767-1), 0x7fff)
903#else
904PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t, int16, (-32767-1), 0x7fff)
905PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t, int16, (-32767-1), 0x7fff)
906PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t, int16, (-32767-1), 0x7fff)
907#endif
908PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t, int16, (-32767-1), 0x7fff)
909PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t, int16, (-32767-1), 0x7fff)
910PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t, int16, (-32767-1), 0x7fff)
911
912#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
913PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, add)
914PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, sub)
915PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, mul)
916#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
917PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, add, UShortAdd)
918PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, sub, UShortSub)
919PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, mul, UShortMult)
920#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16)
921PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, add, 0xffff)
922PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, sub, 0xffff)
923PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, mul, 0xffff)
924#else
925PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t, uint16, 0xffff)
926PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t, uint16, 0xffff)
927PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t, uint16, 0xffff)
928#endif
929PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t, uint16, 0xffff)
930PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t, uint16, 0xffff)
931
932#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
933PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, add)
934PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, sub)
935PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, mul)
936#elif defined(PSNIP_SAFE_HAVE_LARGER_INT32)
937PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, add, (-0x7fffffffLL-1), 0x7fffffffLL)
938PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, sub, (-0x7fffffffLL-1), 0x7fffffffLL)
939PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, mul, (-0x7fffffffLL-1), 0x7fffffffLL)
940#else
941PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
942PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
943PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
944#endif
945PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
946PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
947PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL)
948
949#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
950PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, add)
951PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, sub)
952PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, mul)
953#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
954PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, add, UIntAdd)
955PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, sub, UIntSub)
956PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, mul, UIntMult)
957#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32)
958PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, add, 0xffffffffUL)
959PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, sub, 0xffffffffUL)
960PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, mul, 0xffffffffUL)
961#else
962PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t, uint32, 0xffffffffUL)
963PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t, uint32, 0xffffffffUL)
964PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t, uint32, 0xffffffffUL)
965#endif
966PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t, uint32, 0xffffffffUL)
967PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t, uint32, 0xffffffffUL)
968
969#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
970PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, add)
971PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, sub)
972PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, mul)
973#elif defined(PSNIP_SAFE_HAVE_LARGER_INT64)
974PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, add, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
975PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, sub, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
976PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, mul, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
977#else
978PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
979PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
980PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
981#endif
982PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
983PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
984PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
985
986#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW)
987PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, add)
988PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, sub)
989PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, mul)
990#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32)
991PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, add, ULongLongAdd)
992PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, sub, ULongLongSub)
993PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, mul, ULongLongMult)
994#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64)
995PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, add, 0xffffffffffffffffULL)
996PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, sub, 0xffffffffffffffffULL)
997PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, mul, 0xffffffffffffffffULL)
998#else
999PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1000PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1001PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1002#endif
1003PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t, uint64, 0xffffffffffffffffULL)
1004PSNIP_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) */