File indexing completed on 2026-08-06 08:48:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef C_SAFE_MATH_IMPL
0016 #define C_SAFE_MATH_IMPL
0017
0018 #if defined _MSC_VER
0019
0020 #pragma warning(disable:4710 4711)
0021 #endif
0022
0023 #ifdef __cplusplus
0024 extern "C"
0025 {
0026 #endif
0027
0028
0029
0030 #define VISUAL_STUDIO_COMPILER 0
0031 #define CLANG_COMPILER 1
0032 #define GCC_COMPILER 2
0033 #define UNKNOWN_COMPILER -1
0034
0035
0036
0037 #if defined __clang__
0038 #define SAFEINT_COMPILER CLANG_COMPILER
0039 #elif defined __GNUC__
0040 #define SAFEINT_COMPILER GCC_COMPILER
0041 #elif defined _MSC_VER
0042 #define SAFEINT_COMPILER VISUAL_STUDIO_COMPILER
0043 #else
0044 #define SAFEINT_COMPILER UNKNOWN_COMPILER
0045 #endif
0046
0047
0048 #if SAFEINT_COMPILER == GCC_COMPILER || SAFEINT_COMPILER == CLANG_COMPILER
0049 #define SAFEINT_NORETURN __attribute__((noreturn))
0050 #define SAFEINT_STDCALL
0051 #define SAFEINT_VISIBLE __attribute__ ((__visibility__("default")))
0052 #define SAFEINT_WEAK __attribute__ ((weak))
0053 #else
0054 #define SAFEINT_NORETURN __declspec(noreturn)
0055 #define SAFEINT_STDCALL __stdcall
0056 #define SAFEINT_VISIBLE
0057 #define SAFEINT_WEAK
0058 #endif
0059
0060 #if SAFEINT_COMPILER == VISUAL_STUDIO_COMPILER
0061
0062 #if !defined __STDC_WANT_SECURE_LIB__
0063 #define __STDC_WANT_SECURE_LIB__ 0
0064 #endif
0065
0066 #endif
0067
0068 #include <stdint.h>
0069 #include <stdbool.h>
0070 #include <limits.h>
0071
0072
0073
0074 #define SAFEINT_MULTIPLY_MATH 0
0075 #define SAFEINT_MULTIPLY_INTRINSICS 1
0076 #define SAFEINT_MULTIPLY_BUILTIN 2
0077 #define SAFEINT_MULTIPLY_INT128 3
0078
0079
0080 #if !defined SAFEINT_HAS_INT128
0081
0082 #if defined __SIZEOF_INT128__ && __SIZEOF_INT128__ == 16
0083 #define SAFEINT_HAS_INT128 1
0084 #else
0085 #define SAFEINT_HAS_INT128 0
0086 #endif
0087
0088 #endif
0089
0090 #if SAFEINT_HAS_INT128
0091 #define SAFEINT_MULTIPLY_METHOD SAFEINT_MULTIPLY_INT128
0092 #else
0093
0094 #if !defined SAFEINT_USE_INTRINSICS
0095
0096 #if SAFEINT_COMPILER == VISUAL_STUDIO_COMPILER
0097 #if defined _M_AMD64 && !defined _M_ARM64EC
0098 #include <intrin.h>
0099 #define SAFEINT_MULTIPLY_METHOD SAFEINT_MULTIPLY_INTRINSICS
0100 #else
0101 #define SAFEINT_MULTIPLY_METHOD SAFEINT_MULTIPLY_MATH
0102 #endif
0103
0104 #else
0105
0106
0107 #if SAFEINT_COMPILER == CLANG_COMPILER || SAFEINT_COMPILER == GCC_COMPILER
0108 #define SAFEINT_MULTIPLY_METHOD SAFEINT_MULTIPLY_BUILTIN
0109 #else
0110 #define SAFEINT_MULTIPLY_METHOD SAFEINT_MULTIPLY_MATH
0111 #endif
0112 #endif
0113
0114 #endif
0115 #endif
0116
0117
0118
0119
0120
0121
0122
0123 #if !defined SAFE_MATH_FAIL_DEFINED
0124 #define SAFE_MATH_FAIL_DEFINED
0125 #include <stdlib.h>
0126
0127 SAFEINT_NORETURN
0128 static inline void safe_math_fail(const char* msg)
0129 {
0130 (void)msg;
0131 abort();
0132 }
0133 #endif
0134
0135 #if !defined UINT64_MAX
0136
0137 #define INT8_MIN (-127i8 - 1)
0138 #define INT16_MIN (-32767i16 - 1)
0139 #define INT32_MIN (-2147483647i32 - 1)
0140 #define INT64_MIN (-9223372036854775807i64 - 1)
0141 #define INT8_MAX 127i8
0142 #define INT16_MAX 32767i16
0143 #define INT32_MAX 2147483647i32
0144 #define INT64_MAX 9223372036854775807i64
0145 #define UINT8_MAX 0xffui8
0146 #define UINT16_MAX 0xffffui16
0147 #define UINT32_MAX 0xffffffffui32
0148 #define UINT64_MAX 0xffffffffffffffffui64
0149
0150 #endif
0151
0152
0153
0154
0155
0156
0157 static inline int32_t negate32(int32_t in) { return (int32_t)(~(uint32_t)in + 1); }
0158 static inline int64_t negate64(int64_t in) { return (int64_t)(~(uint64_t)in + 1); }
0159
0160 static inline uint32_t safe_abs32(int32_t in)
0161 {
0162 if (in < 0)
0163 return ~(uint32_t)in + 1;
0164
0165 return (uint32_t)in;
0166 }
0167
0168 static inline uint64_t safe_abs64(int64_t in)
0169 {
0170 if (in < 0)
0171 return ~(uint64_t)in + 1;
0172
0173 return (uint64_t)in;
0174 }
0175
0176
0177
0178 static inline int check_cast_int8_int32(int32_t in) { return (in < INT8_MIN || in > INT8_MAX); }
0179 static inline int check_cast_int8_uint32(uint32_t in) { return in > INT8_MAX; }
0180 static inline int check_cast_int8_int64(int64_t in) { return in < INT8_MIN || in > INT8_MAX; }
0181 static inline int check_cast_int8_uint64(uint64_t in) { return (in > INT8_MAX); }
0182 static inline int check_cast_int16_int32(int32_t in) { return in < INT16_MIN || in > INT16_MAX; }
0183 static inline int check_cast_int16_uint32(uint32_t in) { return (in > INT16_MAX); }
0184 static inline int check_cast_int16_int64(int64_t in) { return (in < INT16_MIN || in > INT16_MAX); }
0185 static inline int check_cast_int16_uint64(uint64_t in) { return (in > INT16_MAX); }
0186 static inline int check_cast_int32_uint32(uint32_t in) { return (in > INT32_MAX); }
0187 static inline int check_cast_int32_int64(int64_t in) { return (in < INT32_MIN || in > INT32_MAX); }
0188 static inline int check_cast_int32_uint64(uint64_t in) { return (in > INT32_MAX); }
0189 static inline int check_cast_int64_uint64(uint64_t in) { return (in > INT64_MAX); }
0190 static inline int check_cast_uint8_int32(int32_t in) { return (in < 0 || in > UINT8_MAX); }
0191 static inline int check_cast_uint8_uint32(uint32_t in) { return (in > UINT8_MAX); }
0192 static inline int check_cast_uint8_int64(int64_t in) { return (in < 0 || in > UINT8_MAX); }
0193 static inline int check_cast_uint8_uint64(uint64_t in) { return (in > UINT8_MAX); }
0194 static inline int check_cast_uint16_int32(int32_t in) { return (in < 0 || in > UINT16_MAX); }
0195 static inline int check_cast_uint16_uint32(uint32_t in) { return (in > UINT16_MAX); }
0196 static inline int check_cast_uint16_int64(int64_t in) { return (in < 0 || in > UINT16_MAX); }
0197 static inline int check_cast_uint16_uint64(uint64_t in) { return (in > UINT16_MAX); }
0198 static inline int check_cast_uint32_int32(int32_t in) { return (in < 0); }
0199 static inline int check_cast_uint32_int64(int64_t in) { return (in < 0 || in > UINT32_MAX); }
0200 static inline int check_cast_uint32_uint64(uint64_t in) { return (in > UINT32_MAX); }
0201 static inline int check_cast_uint64_int64(int64_t in) { return (in < 0); }
0202
0203 static inline int8_t safe_cast_int8_int32(int32_t in)
0204 {
0205 if (!check_cast_int8_int32(in))
0206 safe_math_fail("safe_math_fail safe_cast_int8_int32");
0207
0208 return (int8_t)in;
0209 }
0210
0211 static inline int8_t safe_cast_int8_uint32(uint32_t in)
0212 {
0213 if (check_cast_int8_uint32(in))
0214 safe_math_fail("safe_math_fail safe_cast_int8_uint32");
0215
0216 return (int8_t)in;
0217 }
0218
0219 static inline int8_t safe_cast_int8_int64(int64_t in)
0220 {
0221 if (check_cast_int8_int64(in))
0222 safe_math_fail("safe_math_fail safe_cast_int8_int64");
0223
0224 return (int8_t)in;
0225 }
0226
0227 static inline int8_t safe_cast_int8_uint64(uint64_t in)
0228 {
0229 if (check_cast_int8_uint64(in))
0230 safe_math_fail("safe_math_fail safe_cast_int8_uint64");
0231
0232 return (int8_t)in;
0233 }
0234
0235 static inline int16_t safe_cast_int16_int32(int32_t in)
0236 {
0237 if (check_cast_int16_int32(in))
0238 safe_math_fail("safe_math_fail safe_cast_int16_int32");
0239
0240 return (int16_t)in;
0241 }
0242
0243 static inline int16_t safe_cast_int16_uint32(uint32_t in)
0244 {
0245 if (check_cast_int16_uint32(in))
0246 safe_math_fail("safe_math_fail safe_cast_int16_uint32");
0247
0248 return (int16_t)in;
0249 }
0250
0251 static inline int16_t safe_cast_int16_int64(int64_t in)
0252 {
0253 if (check_cast_int16_int64(in))
0254 safe_math_fail("safe_math_fail safe_cast_int16_int64");
0255
0256 return (int16_t)in;
0257 }
0258
0259 static inline int16_t safe_cast_int16_uint64(uint64_t in)
0260 {
0261 if (in > INT16_MAX)
0262 safe_math_fail("safe_math_fail safe_cast_int16_uint64");
0263
0264 return (int16_t)in;
0265 }
0266
0267 static inline int32_t safe_cast_int32_uint32(uint32_t in)
0268 {
0269 if (check_cast_int32_uint32(in))
0270 safe_math_fail("safe_math_fail safe_cast_int32_uint32");
0271
0272 return (int32_t)in;
0273 }
0274
0275 static inline int32_t safe_cast_int32_int64(int64_t in)
0276 {
0277 if (check_cast_int32_int64(in))
0278 safe_math_fail("safe_math_fail safe_cast_int32_int64");
0279
0280 return (int32_t)in;
0281 }
0282
0283 static inline int32_t safe_cast_int32_uint64(uint64_t in)
0284 {
0285 if (check_cast_int32_uint64(in))
0286 safe_math_fail("safe_math_fail safe_cast_int32_uint64");
0287
0288 return (int32_t)in;
0289 }
0290
0291 static inline int64_t safe_cast_int64_uint64(uint64_t in)
0292 {
0293 if (check_cast_int64_uint64(in))
0294 safe_math_fail("safe_math_fail safe_cast_int64_uint64");
0295
0296 return (int64_t)in;
0297 }
0298
0299 static inline uint8_t safe_cast_uint8_int32(int32_t in)
0300 {
0301 if (check_cast_uint8_int32(in))
0302 safe_math_fail("safe_math_fail safe_cast_uint8_int32");
0303
0304 return (uint8_t)in;
0305 }
0306
0307 static inline uint8_t safe_cast_uint8_uint32(uint32_t in)
0308 {
0309 if (check_cast_uint8_uint32(in))
0310 safe_math_fail("safe_math_fail safe_cast_uint8_uint32");
0311
0312 return (uint8_t)in;
0313 }
0314
0315 static inline uint8_t safe_cast_uint8_int64(int64_t in)
0316 {
0317 if (check_cast_uint8_int64(in))
0318 safe_math_fail("safe_math_fail safe_cast_uint8_int64");
0319
0320 return (uint8_t)in;
0321 }
0322
0323 static inline uint8_t safe_cast_uint8_uint64(uint64_t in)
0324 {
0325 if (check_cast_uint8_uint64(in))
0326 safe_math_fail("safe_math_fail safe_cast_uint8_uint64");
0327
0328 return (uint8_t)in;
0329 }
0330
0331 static inline uint16_t safe_cast_uint16_int32(int32_t in)
0332 {
0333 if (check_cast_uint16_int32(in))
0334 safe_math_fail("safe_math_fail safe_cast_uint16_int32");
0335
0336 return (uint16_t)in;
0337 }
0338
0339 static inline uint16_t safe_cast_uint16_uint32(uint32_t in)
0340 {
0341 if (check_cast_uint16_uint32(in))
0342 safe_math_fail("safe_math_fail safe_cast_uint16_uint32");
0343
0344 return (uint16_t)in;
0345 }
0346
0347 static inline uint16_t safe_cast_uint16_int64(int64_t in)
0348 {
0349 if (check_cast_uint16_int64(in))
0350 safe_math_fail("safe_math_fail safe_cast_uint16_int64");
0351
0352 return (uint16_t)in;
0353 }
0354
0355 static inline uint16_t safe_cast_uint16_uint64(uint64_t in)
0356 {
0357 if (check_cast_uint16_uint64(in))
0358 safe_math_fail("safe_math_fail safe_cast_int16_uint64");
0359
0360 return (uint16_t)in;
0361 }
0362
0363 static inline uint32_t safe_cast_uint32_int32(int32_t in)
0364 {
0365 if (check_cast_uint32_int32(in))
0366 safe_math_fail("safe_math_fail safe_cast_uint32_int32");
0367
0368 return (uint32_t)in;
0369 }
0370
0371 static inline uint32_t safe_cast_uint32_int64(int64_t in)
0372 {
0373 if (check_cast_uint32_int64(in))
0374 safe_math_fail("safe_math_fail safe_cast_int32_int64");
0375
0376 return (uint32_t)in;
0377 }
0378
0379 static inline uint32_t safe_cast_uint32_uint64(uint64_t in)
0380 {
0381 if (check_cast_uint32_uint64(in))
0382 safe_math_fail("safe_math_fail safe_cast_uint32_uint64");
0383
0384 return (uint32_t)in;
0385 }
0386
0387 static inline uint64_t safe_cast_uint64_int64(int64_t in)
0388 {
0389 if (check_cast_uint64_int64(in))
0390 safe_math_fail("safe_math_fail safe_cast_int64_uint64");
0391
0392 return (uint64_t)in;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 static inline int32_t safe_add_int32_int32(int32_t a, int32_t b)
0409 {
0410 return safe_cast_int32_int64((int64_t)a + b);
0411 }
0412
0413 static inline bool check_add_int32_int32(int32_t a, int32_t b, int32_t* ret)
0414 {
0415 int64_t tmp = (int64_t)a + b;
0416 *ret = (int32_t)tmp;
0417 return check_cast_int32_int64(tmp) == 0;
0418 }
0419
0420 static inline int32_t safe_add_int32_uint32(int32_t a, uint32_t b)
0421 {
0422 return safe_cast_int32_int64((int64_t)a + b);
0423 }
0424
0425 static inline bool check_add_int32_uint32(int32_t a, uint32_t b, int32_t* ret)
0426 {
0427 int64_t tmp = (int64_t)a + b;
0428 *ret = (int32_t)tmp;
0429 return check_cast_int32_int64(tmp) == 0;
0430 }
0431
0432 static inline int32_t safe_add_int32_int64(int32_t a, int64_t b)
0433 {
0434 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0435
0436 if (a >= 0)
0437 {
0438
0439 if (b >= 0 && tmp < a)
0440 safe_math_fail("safe_math_fail safe_add_int32_int64");
0441 }
0442 else
0443 {
0444
0445 if (b < 0 && tmp > a)
0446 safe_math_fail("safe_math_fail safe_add_int32_int64");
0447 }
0448
0449 return safe_cast_int32_int64(tmp);
0450 }
0451
0452 static inline bool check_add_int32_int64(int32_t a, int64_t b, int32_t* ret)
0453 {
0454 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0455 *ret = (int32_t)tmp;
0456
0457 if (a >= 0)
0458 {
0459
0460 if (b >= 0 && tmp < a)
0461 return false;
0462 }
0463 else
0464 {
0465
0466 if (b < 0 && tmp > a)
0467 return false;
0468 }
0469
0470 return check_cast_int32_int64(tmp) == 0;
0471 }
0472
0473 static inline int32_t safe_add_int32_uint64(int32_t a, uint64_t b)
0474 {
0475 if ((uint32_t)(b >> 32) == 0)
0476 {
0477
0478
0479 uint32_t tmp = (uint32_t)a + (uint32_t)b;
0480
0481 if ((int32_t)tmp >= a)
0482 {
0483 return (int32_t)tmp;
0484 }
0485 }
0486
0487 safe_math_fail("safe_math_fail safe_add_int32_uint64");
0488 }
0489
0490 static inline bool check_add_int32_uint64(int32_t a, uint64_t b, int32_t* ret)
0491 {
0492 if ((uint32_t)(b >> 32) == 0)
0493 {
0494
0495
0496 uint32_t tmp = (uint32_t)a + (uint32_t)b;
0497 *ret = (int32_t)tmp;
0498
0499 if ((int32_t)tmp >= a)
0500 {
0501 return true;
0502 }
0503 }
0504
0505 return false;
0506 }
0507
0508 static inline uint32_t safe_add_uint32_int32(uint32_t a, int32_t b)
0509 {
0510 return safe_cast_uint32_int64((int64_t)a + b);
0511 }
0512
0513 static inline bool check_add_uint32_int32(uint32_t a, int32_t b, uint32_t* ret)
0514 {
0515 int64_t tmp = (int64_t)a + b;
0516 *ret = (uint32_t)tmp;
0517 return check_cast_uint32_int64(tmp) == 0;
0518 }
0519
0520 static inline uint32_t safe_add_uint32_uint32(uint32_t a, uint32_t b)
0521 {
0522 uint32_t tmp = a + b;
0523
0524 if (tmp < a)
0525 {
0526 safe_math_fail("safe_math_fail safe_add_uint32_uint32");
0527 }
0528
0529 return tmp;
0530 }
0531
0532 static inline bool check_add_uint32_uint32(uint32_t a, uint32_t b, uint32_t* ret)
0533 {
0534 uint32_t tmp = a + b;
0535 *ret = tmp;
0536 return tmp >= a;
0537 }
0538
0539 static inline uint32_t safe_add_uint32_int64(uint32_t a, int64_t b)
0540 {
0541 if (b < 0)
0542 {
0543 if (a >= safe_abs64(b))
0544 {
0545 return (uint32_t)(a + b);
0546 }
0547 }
0548 else
0549 {
0550
0551 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0552
0553
0554
0555 return safe_cast_uint32_uint64(tmp);
0556 }
0557
0558 safe_math_fail("safe_math_fail safe_add_uint32_int64");
0559 }
0560
0561 static inline bool check_add_uint32_int64(uint32_t a, int64_t b, uint32_t* ret)
0562 {
0563 if (b < 0)
0564 {
0565 if (a >= safe_abs64(b))
0566 {
0567 *ret = (uint32_t)(a + b);
0568 return true;
0569 }
0570 }
0571 else
0572 {
0573
0574 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0575
0576
0577
0578 *ret = (uint32_t)tmp;
0579 return check_cast_uint32_uint64(tmp) == 0;
0580 }
0581
0582 return false;
0583 }
0584
0585 static inline uint32_t safe_add_uint32_uint64(uint32_t a, uint64_t b)
0586 {
0587 uint64_t tmp = (uint64_t)a + b;
0588
0589 if (tmp >= a && tmp <= UINT32_MAX)
0590 {
0591 return (uint32_t)tmp;
0592 }
0593
0594 safe_math_fail("safe_math_fail safe_add_uint32_uint64");
0595 }
0596
0597 static inline bool check_add_uint32_uint64(uint32_t a, uint64_t b, uint32_t* ret)
0598 {
0599 uint64_t tmp = (uint64_t)a + b;
0600 *ret = (uint32_t)tmp;
0601
0602 return (tmp >= a && tmp <= UINT32_MAX);
0603 }
0604
0605 static inline int64_t safe_add_int64_int32(int64_t a, int32_t b)
0606 {
0607 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0608
0609 if (a >= 0)
0610 {
0611
0612 if (b >= 0 && tmp < a)
0613 safe_math_fail("safe_math_fail safe_add_int64_int32");
0614 }
0615 else
0616 {
0617
0618 if (b < 0 && tmp > a)
0619 safe_math_fail("safe_math_fail safe_add_int64_int32");
0620 }
0621
0622 return tmp;
0623 }
0624
0625 static inline bool check_add_int64_int32(int64_t a, int32_t b, int64_t* ret)
0626 {
0627 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0628 *ret = tmp;
0629
0630 if (a >= 0)
0631 {
0632
0633 if (b >= 0 && tmp < a)
0634 return false;
0635 }
0636 else
0637 {
0638
0639 if (b < 0 && tmp > a)
0640 return false;
0641 }
0642
0643 return true;
0644 }
0645
0646 static inline int64_t safe_add_int64_uint32(int64_t a, uint32_t b)
0647 {
0648 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0649
0650 if ((int64_t)tmp >= a)
0651 {
0652 return (int64_t)tmp;
0653 }
0654
0655 safe_math_fail("safe_math_fail safe_add_int64_uint32");
0656 }
0657
0658 static inline bool check_add_int64_uint32(int64_t a, uint32_t b, int64_t* ret)
0659 {
0660 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0661 *ret = (int64_t)tmp;
0662
0663 return ((int64_t)tmp >= a);
0664 }
0665
0666 static inline int64_t safe_add_int64_int64(int64_t a, int64_t b)
0667 {
0668 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0669
0670 if (a >= 0)
0671 {
0672
0673 if (b >= 0 && tmp < a)
0674 safe_math_fail("safe_math_fail safe_add_int64_int64");
0675 }
0676 else
0677 {
0678
0679 if (b < 0 && tmp > a)
0680 safe_math_fail("safe_math_fail safe_add_int64_int64");
0681 }
0682
0683 return tmp;
0684 }
0685
0686 static inline bool check_add_int64_int64(int64_t a, int64_t b, int64_t* ret)
0687 {
0688 int64_t tmp = (int64_t)((uint64_t)a + (uint64_t)b);
0689 *ret = tmp;
0690
0691 if (a >= 0)
0692 {
0693
0694 if (b >= 0 && tmp < a)
0695 return false;
0696 }
0697 else
0698 {
0699
0700 if (b < 0 && tmp > a)
0701 return false;
0702 }
0703
0704 return true;
0705 }
0706
0707 static inline int64_t safe_add_int64_uint64(int64_t a, uint64_t b)
0708 {
0709 uint64_t tmp = (uint64_t)a + b;
0710
0711 if ((int64_t)tmp >= a)
0712 {
0713 return (int64_t)tmp;
0714 }
0715
0716 safe_math_fail("safe_math_fail safe_add_int64_uint64");
0717 }
0718
0719 static inline bool check_add_int64_uint64(int64_t a, uint64_t b, int64_t* ret)
0720 {
0721 uint64_t tmp = (uint64_t)a + b;
0722 *ret = (int64_t)tmp;
0723
0724 return ((int64_t)tmp >= a);
0725 }
0726
0727 static inline uint64_t safe_add_uint64_int32(uint64_t a, int32_t b)
0728 {
0729 uint64_t tmp = 0;
0730
0731 if (b < 0)
0732 {
0733
0734 tmp = safe_abs32(b);
0735
0736 if (tmp <= a)
0737 {
0738 return a - tmp;
0739 }
0740 }
0741 else
0742 {
0743
0744 tmp = (uint64_t)a + (uint64_t)b;
0745
0746
0747 if (tmp >= a)
0748 {
0749 return tmp;
0750 }
0751 }
0752
0753 safe_math_fail("safe_math_fail safe_add_uint64_int32");
0754 }
0755
0756 static inline bool check_add_uint64_int32(uint64_t a, int32_t b, uint64_t* ret)
0757 {
0758 uint64_t tmp = 0;
0759
0760 if (b < 0)
0761 {
0762
0763 tmp = safe_abs32(b);
0764
0765 if (tmp <= a)
0766 {
0767 *ret = a - tmp;
0768 return true;
0769 }
0770 }
0771 else
0772 {
0773
0774 tmp = (uint64_t)a + (uint64_t)b;
0775
0776
0777 if (tmp >= a)
0778 {
0779 *ret = tmp;
0780 return true;
0781 }
0782 }
0783
0784 return false;
0785 }
0786
0787
0788 static inline uint64_t safe_add_uint64_uint32(uint64_t a, uint32_t b)
0789 {
0790 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0791
0792
0793 if (tmp >= a)
0794 {
0795 return tmp;
0796 }
0797
0798 safe_math_fail("safe_math_fail safe_add_uint64_uint32");
0799 }
0800
0801 static inline bool check_add_uint64_uint32(uint64_t a, uint32_t b, uint64_t* ret)
0802 {
0803 uint64_t tmp = (uint64_t)a + (uint64_t)b;
0804 *ret = tmp;
0805
0806
0807 return (tmp >= a);
0808 }
0809
0810 static inline uint64_t safe_add_uint64_int64(uint64_t a, int64_t b)
0811 {
0812 uint64_t tmp = 0;
0813
0814 if (b < 0)
0815 {
0816
0817 tmp = safe_abs64(b);
0818
0819 if (tmp <= a)
0820 {
0821 return a - tmp;
0822 }
0823 }
0824 else
0825 {
0826
0827 tmp = (uint64_t)a + (uint64_t)b;
0828
0829
0830 if (tmp >= a)
0831 {
0832 return tmp;
0833 }
0834 }
0835
0836 safe_math_fail("safe_math_fail safe_add_uint64_int64");
0837 }
0838
0839 static inline bool check_add_uint64_int64(uint64_t a, int64_t b, uint64_t* ret)
0840 {
0841 uint64_t tmp = 0;
0842
0843 if (b < 0)
0844 {
0845
0846 tmp = safe_abs64(b);
0847
0848 if (tmp <= a)
0849 {
0850 *ret = a - tmp;
0851 return true;
0852 }
0853 }
0854 else
0855 {
0856
0857 tmp = (uint64_t)a + (uint64_t)b;
0858
0859
0860 if (tmp >= a)
0861 {
0862 *ret = tmp;
0863 return true;
0864 }
0865 }
0866
0867 return false;
0868 }
0869
0870 static inline uint64_t safe_add_uint64_uint64(uint64_t a, uint64_t b)
0871 {
0872 uint64_t tmp = a + b;
0873
0874 if(tmp < a)
0875 safe_math_fail("safe_math_fail safe_add_uint64_uint64");
0876
0877 return tmp;
0878 }
0879
0880 static inline bool check_add_uint64_uint64(uint64_t a, uint64_t b, uint64_t* ret)
0881 {
0882 uint64_t tmp = a + b;
0883 *ret = tmp;
0884 return (tmp >= a);
0885 }
0886
0887
0888
0889
0890 #define SAFE_INT_MUL_FAIL 0
0891 #define SAFE_INT_MUL_SUCCESS 1
0892
0893
0894 #if SAFEINT_MULTIPLY_METHOD == SAFEINT_MULTIPLY_INT128
0895
0896 static inline int MultiplyUint64(uint64_t a, uint64_t b, uint64_t* pRet)
0897 {
0898 unsigned __int128 tmp = (unsigned __int128)a * (unsigned __int128)b;
0899
0900 if ((tmp >> 64) == 0)
0901 {
0902 *pRet = (uint64_t)tmp;
0903 return SAFE_INT_MUL_SUCCESS;
0904 }
0905
0906 return SAFE_INT_MUL_FAIL;
0907 }
0908
0909 static inline int MultiplyInt64(int64_t a, int64_t b, int64_t* pRet)
0910 {
0911 __int128 tmp = (__int128)a * (__int128)b;
0912 int64_t tmp_high = (int64_t)((unsigned __int128)tmp >> 64);
0913 *pRet = (int64_t)tmp;
0914
0915
0916 if ((a ^ b) < 0)
0917 {
0918 if ((tmp_high == -1 && *pRet < 0) ||
0919 (tmp_high == 0 && *pRet == 0))
0920 {
0921 return SAFE_INT_MUL_SUCCESS;
0922 }
0923 }
0924 else
0925 {
0926 if (tmp_high == 0 && (uint64_t)*pRet <= (uint64_t)INT64_MAX)
0927 {
0928 return SAFE_INT_MUL_SUCCESS;
0929 }
0930 }
0931
0932 return SAFE_INT_MUL_FAIL;
0933 }
0934
0935 #elif SAFEINT_MULTIPLY_METHOD == SAFEINT_MULTIPLY_INTRINSICS
0936
0937
0938 static inline int MultiplyUint64(uint64_t a, uint64_t b, uint64_t * pRet)
0939 {
0940 uint64_t ulHigh = 0;
0941 *pRet = _umul128(a, b, &ulHigh);
0942 return ulHigh == 0 ? SAFE_INT_MUL_SUCCESS : SAFE_INT_MUL_FAIL;
0943 }
0944
0945
0946 static inline int MultiplyInt64(int64_t a, int64_t b, int64_t* pRet)
0947 {
0948 int64_t llHigh = 0;
0949 *pRet = _mul128(a, b, &llHigh);
0950
0951
0952
0953
0954
0955 if ((a ^ b) < 0)
0956 {
0957
0958 if (llHigh == -1 && *pRet < 0 ||
0959 llHigh == 0 && *pRet == 0)
0960 {
0961
0962 return SAFE_INT_MUL_SUCCESS;
0963 }
0964 }
0965 else
0966 {
0967
0968
0969 if (llHigh == 0 && (uint64_t)*pRet <= (uint64_t)INT64_MAX)
0970 return SAFE_INT_MUL_SUCCESS;
0971 }
0972 return SAFE_INT_MUL_FAIL;
0973 }
0974 #elif SAFEINT_MULTIPLY_METHOD == SAFEINT_MULTIPLY_BUILTIN
0975
0976 static inline int MultiplyUint64(uint64_t a, uint64_t b, uint64_t* pRet)
0977 {
0978 return !__builtin_umulll_overflow(a, b, (unsigned long long*)pRet) ? SAFE_INT_MUL_SUCCESS : SAFE_INT_MUL_FAIL;
0979 }
0980
0981 static inline int MultiplyInt64(int64_t a, int64_t b, int64_t* pRet)
0982 {
0983 return !__builtin_smulll_overflow(a, b, (long long*)pRet) ? SAFE_INT_MUL_SUCCESS : SAFE_INT_MUL_FAIL;
0984 }
0985
0986 #elif SAFEINT_MULTIPLY_METHOD == SAFEINT_MULTIPLY_MATH
0987
0988 static inline int MultiplyUint64(uint64_t a, uint64_t b, uint64_t* pRet)
0989 {
0990 uint32_t a_high = a >> 32;
0991 uint32_t a_low = (uint32_t)a;
0992 uint32_t b_high = b >> 32;
0993 uint32_t b_low = (uint32_t)b;
0994 uint64_t tmp = 0;
0995 uint64_t tmp2 = 0;
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006 if (a_high > 0 && b_high > 0)
1007 {
1008 return SAFE_INT_MUL_FAIL;
1009 }
1010
1011 if (a_high > 0)
1012 {
1013 tmp = (uint64_t)a_high * b_low;
1014 }
1015 else
1016 {
1017 tmp = (uint64_t)b_high * a_low;
1018 }
1019
1020 if (tmp >> 32 != 0)
1021 {
1022 return SAFE_INT_MUL_FAIL;
1023 }
1024
1025 tmp2 = (uint64_t)a_low * b_low;
1026 *pRet = (tmp << 32) + tmp2;
1027 return *pRet >= tmp2 ? SAFE_INT_MUL_SUCCESS : SAFE_INT_MUL_FAIL;
1028 }
1029
1030 static inline int MultiplyInt64(int64_t a, int64_t b, int64_t* pRet)
1031 {
1032 bool aNegative = false;
1033 bool bNegative = false;
1034
1035 uint64_t tmp = 0;
1036 int64_t a1 = a;
1037 int64_t b1 = b;
1038
1039 if (a1 < 0)
1040 {
1041 aNegative = true;
1042 a1 = (int64_t)safe_abs64(a1);
1043 }
1044
1045 if (b1 < 0)
1046 {
1047 bNegative = true;
1048 b1 = (int64_t)safe_abs64(b);
1049 }
1050
1051 if (MultiplyUint64((uint64_t)a1, (uint64_t)b1, &tmp))
1052 {
1053
1054 if (aNegative ^ bNegative)
1055 {
1056
1057 if (tmp <= (uint64_t)INT64_MIN)
1058 {
1059 *pRet = (int64_t)negate64((int64_t)tmp);
1060 return SAFE_INT_MUL_SUCCESS;
1061 }
1062 }
1063 else
1064 {
1065
1066 if (tmp <= (uint64_t)INT64_MAX)
1067 {
1068 *pRet = (int64_t)tmp;
1069 return SAFE_INT_MUL_SUCCESS;
1070 }
1071 }
1072 }
1073
1074 return SAFE_INT_MUL_FAIL;
1075 }
1076
1077 #else
1078
1079 # error Intrinsics enabled, no available intrinics defined
1080 #endif
1081
1082 static inline int32_t safe_mul_int32_int32(int32_t a, int32_t b)
1083 {
1084 int64_t tmp = (int64_t)a * (int64_t)b;
1085 return safe_cast_int32_int64(tmp);
1086 }
1087
1088 static inline bool check_mul_int32_int32(int32_t a, int32_t b, int32_t* ret)
1089 {
1090 int64_t tmp = (int64_t)a * (int64_t)b;
1091 *ret = (int32_t)tmp;
1092 return check_cast_int32_int64(tmp) == 0;
1093 }
1094
1095 static inline int32_t safe_mul_int32_uint32(int32_t a, uint32_t b)
1096 {
1097 int64_t tmp = (int64_t)a * (int64_t)b;
1098 return safe_cast_int32_int64(tmp);
1099 }
1100
1101 static inline bool check_mul_int32_uint32(int32_t a, uint32_t b, int32_t* ret)
1102 {
1103 int64_t tmp = (int64_t)a * (int64_t)b;
1104 *ret = (int32_t)tmp;
1105 return check_cast_int32_int64(tmp) == 0;
1106 }
1107
1108 static inline int32_t safe_mul_int32_int64(int32_t a, int64_t b)
1109 {
1110 int64_t tmp = 0;
1111
1112 if (MultiplyInt64((int64_t)a, b, &tmp))
1113 {
1114 return safe_cast_int32_int64(tmp);
1115 }
1116
1117 safe_math_fail("safe_math_fail safe_mul_int32_int64");
1118 }
1119
1120 static inline bool check_mul_int32_int64(int32_t a, int64_t b, int32_t* ret)
1121 {
1122 int64_t tmp = 0;
1123
1124 if (MultiplyInt64((int64_t)a, b, &tmp))
1125 {
1126 *ret = (int32_t)tmp;
1127 return check_cast_int32_int64(tmp) == 0;
1128 }
1129
1130 return false;
1131 }
1132
1133 static inline int32_t safe_mul_int32_uint64(int32_t a, uint64_t b)
1134 {
1135 uint64_t tmp = 0;
1136 if (a < 0)
1137 {
1138
1139 uint64_t a2 = safe_abs64(a);
1140 if (MultiplyUint64(a2, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)INT32_MAX + 1)
1141 {
1142
1143 return (int32_t)(tmp + 1);
1144 }
1145 }
1146 else
1147 {
1148 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= INT32_MAX)
1149 {
1150 return (int32_t)tmp;
1151 }
1152 }
1153
1154 safe_math_fail("safe_math_fail safe_mul_int32_uint64");
1155 }
1156
1157 static inline bool check_mul_int32_uint64(int32_t a, uint64_t b, int32_t* ret)
1158 {
1159 uint64_t tmp = 0;
1160 if (a < 0)
1161 {
1162
1163 uint64_t a2 = safe_abs64(a);
1164 if (MultiplyUint64(a2, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)INT32_MAX + 1)
1165 {
1166
1167 *ret = (int32_t)(tmp + 1);
1168 return true;
1169 }
1170 }
1171 else
1172 {
1173 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= INT32_MAX)
1174 {
1175 *ret = (int32_t)tmp;
1176 return true;
1177 }
1178 }
1179
1180 return false;
1181 }
1182
1183 static inline uint32_t safe_mul_uint32_int32(uint32_t a, int32_t b)
1184 {
1185 int64_t tmp = (int64_t)a * (int64_t)b;
1186 return safe_cast_uint32_int64(tmp);
1187 }
1188
1189 static inline bool check_mul_uint32_int32(uint32_t a, int32_t b, uint32_t* ret)
1190 {
1191 int64_t tmp = (int64_t)a * (int64_t)b;
1192 *ret = (uint32_t)tmp;
1193 return check_cast_uint32_int64(tmp) == 0;
1194 }
1195
1196 static inline uint32_t safe_mul_uint32_uint32(uint32_t a, uint32_t b)
1197 {
1198 uint64_t tmp = (uint64_t)a * (uint64_t)b;
1199 return safe_cast_uint32_uint64(tmp);
1200 }
1201
1202 static inline bool check_mul_uint32_uint32(uint32_t a, uint32_t b, uint32_t* ret)
1203 {
1204 uint64_t tmp = (uint64_t)a * (uint64_t)b;
1205 *ret = (uint32_t)tmp;
1206 return check_cast_uint32_uint64(tmp) == 0;
1207 }
1208
1209 static inline uint32_t safe_mul_uint32_int64(uint32_t a, int64_t b)
1210 {
1211 int64_t tmp = 0;
1212
1213 if (MultiplyInt64((int64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= UINT32_MAX && tmp >= 0)
1214 {
1215 return (uint32_t)tmp;
1216 }
1217
1218 safe_math_fail("safe_math_fail safe_mul_uint32_int64");
1219 }
1220
1221 static inline bool check_mul_uint32_int64(uint32_t a, int64_t b, uint32_t* ret)
1222 {
1223 int64_t tmp = 0;
1224
1225 if (MultiplyInt64((int64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= UINT32_MAX && tmp >= 0)
1226 {
1227 *ret = (uint32_t)tmp;
1228 return true;
1229 }
1230
1231 return false;
1232 }
1233
1234 static inline uint32_t safe_mul_uint32_uint64(uint32_t a, uint64_t b)
1235 {
1236 uint64_t tmp = 0;
1237
1238 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= UINT32_MAX)
1239 {
1240 return (uint32_t)tmp;
1241 }
1242
1243 safe_math_fail("safe_math_fail safe_mul_uint32_uint64");
1244 }
1245
1246 static inline bool check_mul_uint32_uint64(uint32_t a, uint64_t b, uint32_t* ret)
1247 {
1248 uint64_t tmp = 0;
1249
1250 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= UINT32_MAX)
1251 {
1252 *ret = (uint32_t)tmp;
1253 return true;
1254 }
1255
1256 return false;
1257 }
1258
1259 static inline int64_t safe_mul_int64_int32(int64_t a, int32_t b)
1260 {
1261 int64_t tmp = 0;
1262
1263 if (MultiplyInt64(a, (int64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1264 {
1265 return tmp;
1266 }
1267
1268 safe_math_fail("safe_math_fail safe_mul_int64_int32");
1269 }
1270
1271 static inline bool check_mul_int64_int32(int64_t a, int32_t b, int64_t* ret)
1272 {
1273 int64_t tmp = 0;
1274
1275 if (MultiplyInt64(a, (int64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1276 {
1277 *ret = tmp;
1278 return true;
1279 }
1280
1281 return false;
1282 }
1283
1284 static inline int64_t safe_mul_int64_uint32(int64_t a, uint32_t b)
1285 {
1286 int64_t tmp = 0;
1287
1288 if (MultiplyInt64(a, (int64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1289 {
1290 return tmp;
1291 }
1292
1293 safe_math_fail("safe_math_fail safe_mul_int64_uint32");
1294 }
1295
1296 static inline bool check_mul_int64_uint32(int64_t a, uint32_t b, int64_t* ret)
1297 {
1298 int64_t tmp = 0;
1299
1300 if (MultiplyInt64(a, (int64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1301 {
1302 *ret = tmp;
1303 return true;
1304 }
1305
1306 return false;
1307 }
1308
1309 static inline int64_t safe_mul_int64_int64(int64_t a, int64_t b)
1310 {
1311 int64_t tmp = 0;
1312
1313 if (MultiplyInt64(a, b, &tmp) == SAFE_INT_MUL_SUCCESS)
1314 {
1315 return tmp;
1316 }
1317
1318 safe_math_fail("safe_math_fail safe_mul_int64_int64");
1319 }
1320
1321 static inline bool check_mul_int64_int64(int64_t a, int64_t b, int64_t* ret)
1322 {
1323 int64_t tmp = 0;
1324
1325 if (MultiplyInt64(a, b, &tmp) == SAFE_INT_MUL_SUCCESS)
1326 {
1327 *ret = tmp;
1328 return true;
1329 }
1330
1331 return false;
1332 }
1333
1334 static inline int64_t safe_mul_int64_uint64(int64_t a, uint64_t b)
1335 {
1336 uint64_t tmp = 0;
1337
1338 if (a < 0)
1339 {
1340 uint64_t a2 = safe_abs64(a);
1341
1342 if (MultiplyUint64(a2, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)0x8000000000000000)
1343 {
1344 return negate64((int64_t)tmp);
1345 }
1346 }
1347 else
1348 {
1349 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)INT64_MAX)
1350 {
1351 return (int64_t)tmp;
1352 }
1353 }
1354
1355 safe_math_fail("safe_math_fail safe_mul_int64_uint64");
1356 }
1357
1358 static inline bool check_mul_int64_uint64(int64_t a, uint64_t b, int64_t* ret)
1359 {
1360 uint64_t tmp = 0;
1361
1362 if (a < 0)
1363 {
1364 uint64_t a2 = safe_abs64(a);
1365
1366 if (MultiplyUint64(a2, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)0x8000000000000000)
1367 {
1368 *ret = negate64((int64_t)tmp);
1369 return true;
1370 }
1371 }
1372 else
1373 {
1374 if (MultiplyUint64((uint64_t)a, b, &tmp) == SAFE_INT_MUL_SUCCESS && tmp <= (uint64_t)INT64_MAX)
1375 {
1376 *ret = (int64_t)tmp;
1377 return true;
1378 }
1379 }
1380
1381 return false;
1382 }
1383
1384 static inline uint64_t safe_mul_uint64_int32(uint64_t a, int32_t b)
1385 {
1386 uint64_t tmp;
1387
1388 if (b < 0)
1389 {
1390 if (a == 0)
1391 return 0;
1392
1393 safe_math_fail("safe_math_fail safe_mul_uint64_int32");
1394 }
1395
1396 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1397 {
1398 return tmp;
1399 }
1400
1401 safe_math_fail("safe_math_fail safe_mul_uint64_int32");
1402 }
1403
1404 static inline bool check_mul_uint64_int32(uint64_t a, int32_t b, uint64_t* ret)
1405 {
1406 uint64_t tmp;
1407
1408 if (b < 0)
1409 {
1410 if (a == 0)
1411 {
1412 *ret = 0;
1413 return true;
1414 }
1415
1416 return false;
1417 }
1418
1419 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1420 {
1421 *ret = tmp;
1422 return true;
1423 }
1424
1425 return false;
1426 }
1427
1428 static inline uint64_t safe_mul_uint64_uint32(uint64_t a, uint32_t b)
1429 {
1430 uint64_t tmp;
1431
1432 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1433 {
1434 return tmp;
1435 }
1436
1437 safe_math_fail("safe_math_fail safe_mul_uint64_uint32");
1438 }
1439
1440 static inline bool check_mul_uint64_uint32(uint64_t a, uint32_t b, uint64_t* ret)
1441 {
1442 uint64_t tmp;
1443
1444 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1445 {
1446 *ret = tmp;
1447 return true;
1448 }
1449
1450 return false;
1451 }
1452
1453 static inline uint64_t safe_mul_uint64_int64(uint64_t a, int64_t b)
1454 {
1455 uint64_t tmp;
1456
1457 if (b < 0)
1458 {
1459 if (a == 0)
1460 return 0;
1461
1462 safe_math_fail("safe_math_fail safe_mul_uint64_int32");
1463 }
1464
1465 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1466 {
1467 return tmp;
1468 }
1469
1470 safe_math_fail("safe_math_fail safe_mul_uint64_int64");
1471 }
1472
1473 static inline bool check_mul_uint64_int64(uint64_t a, int64_t b, uint64_t* ret)
1474 {
1475 uint64_t tmp;
1476
1477 if (b < 0)
1478 {
1479 if (a == 0)
1480 {
1481 *ret = 0;
1482 return true;
1483 }
1484
1485 return false;
1486 }
1487
1488 if (MultiplyUint64(a, (uint64_t)b, &tmp) == SAFE_INT_MUL_SUCCESS)
1489 {
1490 *ret = tmp;
1491 return true;
1492 }
1493
1494 return false;
1495 }
1496
1497 static inline uint64_t safe_mul_uint64_uint64(uint64_t a, uint64_t b)
1498 {
1499 uint64_t tmp;
1500
1501 if (MultiplyUint64(a, b, &tmp) == SAFE_INT_MUL_SUCCESS)
1502 {
1503 return tmp;
1504 }
1505
1506 safe_math_fail("safe_math_fail safe_mul_uint64_uint64");
1507 }
1508
1509 static inline bool check_mul_uint64_uint64(uint64_t a, uint64_t b, uint64_t* ret)
1510 {
1511 return (MultiplyUint64(a, b, ret) == SAFE_INT_MUL_SUCCESS);
1512 }
1513
1514 static inline int32_t safe_div_int32_int32(int32_t a, int32_t b)
1515 {
1516 if (b != 0 && !(a == INT32_MIN && b == -1))
1517 {
1518 return a / b;
1519 }
1520 safe_math_fail("safe_math_fail safe_div_int32_int32");
1521 }
1522
1523 static inline bool check_div_int32_int32(int32_t a, int32_t b, int32_t* ret)
1524 {
1525 if (b != 0 && !(a == INT32_MIN && b == -1))
1526 {
1527 *ret = a / b;
1528 return true;
1529 }
1530 return false;
1531 }
1532
1533 static inline int32_t safe_div_int32_uint32(int32_t a, uint32_t b)
1534 {
1535 if (b != 0)
1536 {
1537 return (int32_t)((int64_t)a / (int64_t)b);
1538 }
1539 safe_math_fail("safe_math_fail safe_div_int32_uint32");
1540 }
1541
1542 static inline bool check_div_int32_uint32(int32_t a, uint32_t b, int32_t* ret)
1543 {
1544 if (b != 0)
1545 {
1546 *ret = (int32_t)((int64_t)a / (int64_t)b);
1547 return true;
1548 }
1549
1550 return false;
1551 }
1552
1553 static inline int32_t safe_div_int32_int64(int32_t a, int64_t b)
1554 {
1555 if (b != 0 && !(a == INT32_MIN && b == -1))
1556 {
1557 return (int32_t)(a / b);
1558 }
1559 safe_math_fail("safe_math_fail safe_div_int32_int64");
1560 }
1561
1562 static inline bool check_div_int32_int64(int32_t a, int64_t b, int32_t* ret)
1563 {
1564 if (b != 0 && !(a == INT32_MIN && b == -1))
1565 {
1566 *ret = (int32_t)(a / b);
1567 return true;
1568 }
1569
1570 return false;
1571 }
1572
1573 static inline int32_t safe_div_int32_uint64(int32_t a, uint64_t b)
1574 {
1575 if (b == 0)
1576 {
1577 safe_math_fail("safe_math_fail safe_div_int32_uint64");
1578 }
1579
1580 if (a > 0)
1581 {
1582 return (int32_t)((uint64_t)a / b);
1583 }
1584 else
1585 {
1586 uint64_t a2 = (uint64_t)safe_abs32(a);
1587 a2 /= b;
1588 return (int32_t)negate32((int32_t)a2);
1589 }
1590 }
1591
1592 static inline bool check_div_int32_uint64(int32_t a, uint64_t b, int32_t* ret)
1593 {
1594 if (b == 0)
1595 {
1596 return false;
1597 }
1598
1599 if (a > 0)
1600 {
1601 *ret = (int32_t)((uint64_t)a / b);
1602 return true;
1603 }
1604 else
1605 {
1606 uint64_t a2 = (uint64_t)safe_abs32(a);
1607 a2 /= b;
1608 *ret = (int32_t)negate32((int32_t)a2);
1609 return true;
1610 }
1611 }
1612
1613 static inline uint32_t safe_div_uint32_int32(uint32_t a, int32_t b)
1614 {
1615
1616 if (b == 0)
1617 {
1618 safe_math_fail("safe_math_fail safe_div_uint32_int32");
1619 }
1620
1621 if (a == 0)
1622 {
1623 return 0;
1624 }
1625
1626 if (b > 0)
1627 {
1628 return (a / (uint32_t)b);
1629 }
1630 else
1631 {
1632 uint32_t tmp = safe_abs32(b);
1633
1634 if (a < tmp)
1635 {
1636 return 0;
1637 }
1638 }
1639
1640 safe_math_fail("safe_math_fail safe_div_uint32_int32");
1641 }
1642
1643 static inline bool check_div_uint32_int32(uint32_t a, int32_t b, uint32_t* ret)
1644 {
1645
1646 if (b == 0)
1647 {
1648 return false;
1649 }
1650
1651 if (a == 0)
1652 {
1653 *ret = 0;
1654 return true;
1655 }
1656
1657 if (b > 0)
1658 {
1659 *ret = (a / (uint32_t)b);
1660 return true;
1661 }
1662 else
1663 {
1664 uint32_t tmp = safe_abs32(b);
1665
1666 if (a < tmp)
1667 {
1668 *ret = 0;
1669 return true;
1670 }
1671 }
1672
1673 return false;
1674 }
1675
1676 static inline uint32_t safe_div_uint32_uint32(uint32_t a, uint32_t b)
1677 {
1678 if (b > 0)
1679 {
1680 return (uint32_t)(a / b);
1681 }
1682 safe_math_fail("safe_math_fail safe_div_uint32_uint32");
1683 }
1684
1685 static inline bool check_div_uint32_uint32(uint32_t a, uint32_t b, uint32_t* ret)
1686 {
1687 if (b > 0)
1688 {
1689 *ret = (uint32_t)(a / b);
1690 return true;
1691 }
1692
1693 return false;
1694 }
1695
1696 static inline uint32_t safe_div_uint32_int64(uint32_t a, int64_t b)
1697 {
1698
1699 if (b == 0)
1700 {
1701 safe_math_fail("safe_math_fail safe_div_uint32_int64");
1702 }
1703
1704 if (a == 0)
1705 {
1706 return 0;
1707 }
1708
1709 if (b > 0)
1710 {
1711 return (uint32_t)(a / b);
1712 }
1713 else
1714 {
1715 uint64_t tmp = safe_abs64(b);
1716
1717 if (a < tmp)
1718 {
1719 return 0;
1720 }
1721 }
1722
1723 safe_math_fail("safe_math_fail safe_div_uint32_int64");
1724 }
1725
1726 static inline bool check_div_uint32_int64(uint32_t a, int64_t b, uint32_t* ret)
1727 {
1728
1729 if (b == 0)
1730 {
1731 return false;
1732 }
1733
1734 if (a == 0)
1735 {
1736 *ret = 0;
1737 return true;
1738 }
1739
1740 if (b > 0)
1741 {
1742 *ret = (uint32_t)(a / b);
1743 return true;
1744 }
1745 else
1746 {
1747 uint64_t tmp = safe_abs64(b);
1748
1749 if (a < tmp)
1750 {
1751 *ret = 0;
1752 return true;
1753 }
1754 }
1755
1756 return false;
1757 }
1758
1759 static inline uint32_t safe_div_uint32_uint64(uint32_t a, uint64_t b)
1760 {
1761 if (b > 0)
1762 {
1763 return (uint32_t)(a / b);
1764 }
1765 safe_math_fail("safe_math_fail safe_div_uint32_uint64");
1766 }
1767
1768 static inline bool check_div_uint32_uint64(uint32_t a, uint64_t b, uint32_t* ret)
1769 {
1770 if (b > 0)
1771 {
1772 *ret = (uint32_t)(a / b);
1773 return true;
1774 }
1775 return false;
1776 }
1777
1778 static inline int64_t safe_div_int64_int32(int64_t a, int32_t b)
1779 {
1780 if(b == 0 || (b == -1 && a == INT64_MIN))
1781 safe_math_fail("safe_math_fail safe_div_int64_int32");
1782
1783 return a / b;
1784 }
1785
1786 static inline bool check_div_int64_int32(int64_t a, int32_t b, int64_t* ret)
1787 {
1788 if (b == 0 || (b == -1 && a == INT64_MIN))
1789 return false;
1790
1791 *ret = a / b;
1792 return true;
1793 }
1794
1795 static inline int64_t safe_div_int64_uint32(int64_t a, uint32_t b)
1796 {
1797 if (b == 0)
1798 safe_math_fail("safe_math_fail safe_div_int64_int32");
1799
1800 return a / b;
1801 }
1802
1803 static inline bool check_div_int64_uint32(int64_t a, uint32_t b, int64_t* ret)
1804 {
1805 if (b == 0)
1806 return false;
1807
1808 *ret = a / b;
1809 return true;
1810 }
1811
1812 static inline int64_t safe_div_int64_int64(int64_t a, int64_t b)
1813 {
1814 if (b == 0 || (b == -1 && a == INT64_MIN))
1815 safe_math_fail("safe_math_fail safe_div_int64_int32");
1816
1817 return a / b;
1818 }
1819
1820 static inline bool check_div_int64_int64(int64_t a, int64_t b, int64_t* ret)
1821 {
1822 if (b == 0 || (b == -1 && a == INT64_MIN))
1823 return false;
1824
1825 *ret = a / b;
1826 return true;
1827
1828 }
1829
1830 static inline int64_t safe_div_int64_uint64(int64_t a, uint64_t b)
1831 {
1832 if (b == 0)
1833 safe_math_fail("safe_math_fail safe_div_int64_int32");
1834
1835 if(a >= 0)
1836 {
1837 return (int64_t)((uint64_t)a / b);
1838 }
1839 else
1840 {
1841
1842 uint64_t tmp = safe_abs64(a);
1843 tmp /= b;
1844 return negate64((int64_t)tmp);
1845 }
1846 }
1847
1848 static inline bool check_div_int64_uint64(int64_t a, uint64_t b, int64_t* ret)
1849 {
1850 if (b == 0)
1851 return false;
1852
1853 if(a >= 0)
1854 {
1855 *ret = (int64_t)((uint64_t)a / b);
1856 }
1857 else
1858 {
1859
1860 uint64_t tmp = safe_abs64(a);
1861 tmp /= b;
1862 *ret = negate64((int64_t)tmp);
1863 }
1864 return true;
1865 }
1866
1867 static inline uint64_t safe_div_uint64_int32(uint64_t a, int32_t b)
1868 {
1869
1870 if (b == 0)
1871 {
1872 safe_math_fail("safe_math_fail safe_div_int64_int32");
1873 }
1874
1875 if (a == 0)
1876 {
1877 return 0;
1878 }
1879
1880 if (b > 0)
1881 {
1882 return a / (uint64_t)b;
1883 }
1884 else
1885 {
1886 uint32_t tmp = safe_abs32(b);
1887
1888 if (a < tmp)
1889 {
1890 return 0;
1891 }
1892 }
1893
1894 safe_math_fail("safe_math_fail safe_div_int64_int32");
1895 }
1896
1897 static inline bool check_div_uint64_int32(uint64_t a, int32_t b, uint64_t* ret)
1898 {
1899
1900 if (b == 0)
1901 {
1902 return false;
1903 }
1904
1905 if (a == 0)
1906 {
1907 *ret = 0;
1908 return true;
1909 }
1910
1911 if (b > 0)
1912 {
1913 *ret = a / (uint64_t)b;
1914 return true;
1915 }
1916 else
1917 {
1918 uint32_t tmp = safe_abs32(b);
1919
1920 if (a < tmp)
1921 {
1922 *ret = 0;
1923 return true;
1924 }
1925 }
1926
1927 return false;
1928 }
1929
1930 static inline uint64_t safe_div_uint64_uint32(uint64_t a, uint32_t b)
1931 {
1932 if (b != 0)
1933 return a / b;
1934
1935 safe_math_fail("safe_math_fail safe_div_int64_uint32");
1936 }
1937
1938 static inline bool check_div_uint64_uint32(uint64_t a, uint32_t b, uint64_t* ret)
1939 {
1940 if (b != 0)
1941 {
1942 *ret = a / b;
1943 return true;
1944 }
1945
1946 return false;
1947 }
1948
1949 static inline uint64_t safe_div_uint64_int64(uint64_t a, int64_t b)
1950 {
1951
1952 if (b == 0)
1953 {
1954 safe_math_fail("safe_math_fail safe_div_int64_int32");
1955 }
1956
1957 if (a == 0)
1958 {
1959 return 0;
1960 }
1961
1962 if (b > 0)
1963 {
1964 return a / (uint64_t)b;
1965 }
1966 else
1967 {
1968 uint64_t tmp = safe_abs64(b);
1969
1970 if (a < tmp)
1971 {
1972 return 0;
1973 }
1974 }
1975
1976 safe_math_fail("safe_math_fail safe_div_int64_int32");
1977 }
1978
1979 static inline bool check_div_uint64_int64(uint64_t a, int64_t b, uint64_t* ret)
1980 {
1981
1982 if (b == 0)
1983 {
1984 return false;
1985 }
1986
1987 if (a == 0)
1988 {
1989 *ret = 0;
1990 return true;
1991 }
1992
1993 if (b > 0)
1994 {
1995 *ret = a / (uint64_t)b;
1996 return true;
1997 }
1998 else
1999 {
2000 uint64_t tmp = safe_abs64(b);
2001
2002 if (a < tmp)
2003 {
2004 *ret = 0;
2005 return true;
2006 }
2007 }
2008
2009 return false;
2010 }
2011
2012 static inline uint64_t safe_div_uint64_uint64(uint64_t a, uint64_t b)
2013 {
2014 if (b != 0)
2015 return a / b;
2016
2017 safe_math_fail("safe_math_fail safe_div_int64_uint32");
2018 }
2019
2020 static inline bool check_div_uint64_uint64(uint64_t a, uint64_t b, uint64_t* ret)
2021 {
2022 if (b != 0)
2023 {
2024 *ret = a / b;
2025 return true;
2026 }
2027
2028 return false;
2029 }
2030
2031 static inline int32_t safe_sub_int32_int32(int32_t a, int32_t b)
2032 {
2033 int64_t tmp = (int64_t)a - (int64_t)b;
2034 return safe_cast_int32_int64(tmp);
2035 }
2036
2037 static inline bool check_sub_int32_int32(int32_t a, int32_t b, int32_t* ret)
2038 {
2039 int64_t tmp = (int64_t)a - (int64_t)b;
2040 *ret = (int32_t)tmp;
2041 return check_cast_int32_int64(tmp) == 0;
2042 }
2043
2044 static inline int32_t safe_sub_int32_uint32(int32_t a, uint32_t b)
2045 {
2046 int64_t tmp = (int64_t)a - (int64_t)b;
2047 return safe_cast_int32_int64(tmp);
2048 }
2049
2050 static inline bool check_sub_int32_uint32(int32_t a, uint32_t b, int32_t* ret)
2051 {
2052 int64_t tmp = (int64_t)a - (int64_t)b;
2053 *ret = (int32_t)tmp;
2054 return check_cast_int32_int64(tmp) == 0;
2055 }
2056
2057 static inline int32_t safe_sub_int32_int64(int32_t a, int64_t b)
2058 {
2059
2060
2061
2062
2063
2064
2065 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2066
2067 if (a >= 0)
2068 {
2069
2070 if (b >= 0)
2071 {
2072 if (tmp >= INT32_MIN)
2073 {
2074 return (int32_t)tmp;
2075 }
2076 }
2077 else
2078 {
2079
2080 if (tmp >= a && tmp <= INT32_MAX)
2081 {
2082 return (int32_t)tmp;
2083 }
2084 }
2085 }
2086 else
2087 {
2088
2089
2090 if (b >= 0)
2091 {
2092 if (tmp <= a && tmp >= INT32_MIN)
2093 {
2094 return (int32_t)tmp;
2095 }
2096 }
2097 else
2098 {
2099
2100 if (tmp <= INT32_MAX)
2101 {
2102 return (int32_t)tmp;
2103 }
2104 }
2105 }
2106
2107 safe_math_fail("safe_math_fail safe_sub_int32_int64");
2108 }
2109
2110 static inline bool check_sub_int32_int64(int32_t a, int64_t b, int32_t* ret)
2111 {
2112
2113 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2114
2115 if (a >= 0)
2116 {
2117
2118 if (b >= 0)
2119 {
2120 if (tmp >= INT32_MIN)
2121 {
2122 *ret = (int32_t)tmp;
2123 return true;
2124 }
2125 }
2126 else
2127 {
2128
2129 if (tmp >= a && tmp <= INT32_MAX)
2130 {
2131 *ret = (int32_t)tmp;
2132 return true;
2133 }
2134 }
2135 }
2136 else
2137 {
2138
2139
2140 if (b >= 0)
2141 {
2142 if (tmp <= a && tmp >= INT32_MIN)
2143 {
2144 *ret = (int32_t)tmp;
2145 return true;
2146 }
2147 }
2148 else
2149 {
2150
2151 if (tmp <= INT32_MAX)
2152 {
2153 *ret = (int32_t)tmp;
2154 return true;
2155 }
2156 }
2157 }
2158
2159 return false;
2160 }
2161
2162 static inline int32_t safe_sub_int32_uint64(int32_t a, uint64_t b)
2163 {
2164
2165
2166 const uint64_t AbsMinInt32 = (uint64_t)INT32_MAX + 1;
2167
2168 if (a < 0)
2169 {
2170 if (b <= AbsMinInt32 - safe_abs32(a))
2171 {
2172 return (int32_t)(a - (int64_t)b);
2173 }
2174 }
2175 else
2176 {
2177 if (b <= AbsMinInt32 + (uint64_t)a)
2178 {
2179 return (int32_t)(a - (int64_t)b);
2180 }
2181 }
2182
2183 safe_math_fail("safe_math_fail safe_sub_int32_uint64");
2184 }
2185
2186 static inline bool check_sub_int32_uint64(int32_t a, uint64_t b, int32_t* ret)
2187 {
2188
2189
2190 const uint64_t AbsMinInt32 = (uint64_t)INT32_MAX + 1;
2191
2192 if (a < 0)
2193 {
2194 if (b <= AbsMinInt32 - safe_abs32(a))
2195 {
2196 *ret = (int32_t)(a - (int64_t)b);
2197 return true;
2198 }
2199 }
2200 else
2201 {
2202 if (b <= AbsMinInt32 + (uint64_t)a)
2203 {
2204 *ret = (int32_t)((int64_t)a - (int64_t)b);
2205 return true;
2206 }
2207 }
2208
2209 return false;
2210 }
2211
2212 static inline uint32_t safe_sub_uint32_int32(uint32_t a, int32_t b)
2213 {
2214 int64_t tmp = (int64_t)a - (int64_t)b;
2215 return safe_cast_uint32_int64(tmp);
2216 }
2217
2218 static inline bool check_sub_uint32_int32(uint32_t a, int32_t b, uint32_t* ret)
2219 {
2220 int64_t tmp = (int64_t)a - (int64_t)b;
2221 *ret = (uint32_t)tmp;
2222 return check_cast_uint32_int64(tmp) == 0;
2223 }
2224
2225 static inline uint32_t safe_sub_uint32_uint32(uint32_t a, uint32_t b)
2226 {
2227 if (a >= b)
2228 return a - b;
2229
2230 safe_math_fail("safe_math_fail safe_sub_uint32_uint32");
2231 }
2232
2233 static inline bool check_sub_uint32_uint32(uint32_t a, uint32_t b, uint32_t* ret)
2234 {
2235 if (a >= b)
2236 {
2237 *ret = a - b;
2238 return true;
2239 }
2240
2241 return false;
2242 }
2243
2244 static inline uint32_t safe_sub_uint32_int64(uint32_t a, int64_t b)
2245 {
2246
2247 if (b >= 0)
2248 {
2249 if ((uint64_t)b <= a)
2250 {
2251 return (uint32_t)(a - (uint32_t)b);
2252 }
2253 }
2254 else
2255 {
2256
2257
2258
2259 uint64_t tmp = a + (uint64_t)negate64(b);
2260
2261
2262 if (tmp <= UINT32_MAX)
2263 {
2264 return (uint32_t)tmp;
2265 }
2266 }
2267
2268 safe_math_fail("safe_math_fail safe_sub_uint32_int64");
2269 }
2270
2271 static inline bool check_sub_uint32_int64(uint32_t a, int64_t b, uint32_t* ret)
2272 {
2273
2274 if (b >= 0)
2275 {
2276 if ((uint64_t)b <= a)
2277 {
2278 *ret = (uint32_t)(a - (uint32_t)b);
2279 return true;
2280 }
2281 }
2282 else
2283 {
2284
2285
2286
2287 uint64_t tmp = a + (uint64_t)negate64(b);
2288
2289
2290 if (tmp <= UINT32_MAX)
2291 {
2292 *ret = (uint32_t)tmp;
2293 return true;
2294 }
2295 }
2296
2297 return false;
2298 }
2299
2300 static inline uint32_t safe_sub_uint32_uint64(uint32_t a, uint64_t b)
2301 {
2302 if (a >= b)
2303 return (uint32_t)(a - b);
2304
2305 safe_math_fail("safe_math_fail safe_sub_uint32_uint64");
2306 }
2307
2308 static inline bool check_sub_uint32_uint64(uint32_t a, uint64_t b, uint32_t* ret)
2309 {
2310 if (a >= b)
2311 {
2312 *ret = (uint32_t)(a - b);
2313 return true;
2314 }
2315 return false;
2316 }
2317
2318 static inline int64_t safe_sub_int64_int32(int64_t a, int32_t b)
2319 {
2320
2321
2322
2323
2324
2325
2326
2327 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2328
2329
2330
2331
2332 if ((a >= 0 && b < 0 && tmp < a) ||
2333 (b >= 0 && tmp > a))
2334 {
2335 safe_math_fail("safe_math_fail safe_sub_int64_int32");
2336 }
2337
2338 return tmp;
2339 }
2340
2341 static inline bool check_sub_int64_int32(int64_t a, int32_t b, int64_t* ret)
2342 {
2343 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2344
2345
2346
2347
2348 if ((a >= 0 && b < 0 && tmp < a) ||
2349 (b >= 0 && tmp > a))
2350 {
2351 return false;
2352 }
2353
2354 *ret = tmp;
2355 return true;
2356 }
2357
2358 static inline int64_t safe_sub_int64_uint32(int64_t a, uint32_t b)
2359 {
2360
2361
2362 uint64_t tmp = (uint64_t)a - (uint64_t)b;
2363
2364 if ((int64_t)tmp <= a)
2365 {
2366 return (int64_t)tmp;
2367 }
2368
2369 safe_math_fail("safe_math_fail safe_sub_int64_int64");
2370 }
2371
2372 static inline bool check_sub_int64_uint32(int64_t a, uint32_t b, int64_t* ret)
2373 {
2374 uint64_t tmp = (uint64_t)a - (uint64_t)b;
2375
2376 if ((int64_t)tmp <= a)
2377 {
2378 *ret = (int64_t)tmp;
2379 return true;
2380 }
2381
2382 return false;
2383 }
2384
2385 static inline int64_t safe_sub_int64_int64(int64_t a, int64_t b)
2386 {
2387
2388
2389
2390
2391
2392
2393
2394 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2395
2396
2397
2398
2399 if ((a >= 0 && b < 0 && tmp < a) ||
2400 (b >= 0 && tmp > a))
2401 {
2402 safe_math_fail("safe_math_fail safe_sub_int64_int64");
2403 }
2404
2405 return tmp;
2406 }
2407
2408 static inline bool check_sub_int64_int64(int64_t a, int64_t b, int64_t* ret)
2409 {
2410 int64_t tmp = (int64_t)((uint64_t)a - (uint64_t)b);
2411
2412
2413
2414
2415 if ((a >= 0 && b < 0 && tmp < a) ||
2416 (b >= 0 && tmp > a))
2417 {
2418 return false;
2419 }
2420
2421 *ret = tmp;
2422 return true;
2423 }
2424
2425 static inline int64_t safe_sub_int64_uint64(int64_t a, uint64_t b)
2426 {
2427
2428
2429 uint64_t tmp = (uint64_t)a - b;
2430
2431 if ((int64_t)tmp <= a)
2432 {
2433 return (int64_t)tmp;
2434 }
2435
2436 safe_math_fail("safe_math_fail safe_sub_int64_uint64");
2437 }
2438
2439 static inline bool check_sub_int64_uint64(int64_t a, uint64_t b, int64_t* ret)
2440 {
2441 uint64_t tmp = (uint64_t)a - b;
2442 *ret = (int64_t)tmp;
2443
2444 return ((int64_t)tmp <= a);
2445 }
2446
2447 static inline uint64_t safe_sub_uint64_int32(uint64_t a, int32_t b)
2448 {
2449
2450
2451 if (b >= 0)
2452 {
2453 if ((uint64_t)b <= a)
2454 {
2455 return (uint64_t)(a - (uint64_t)b);
2456 }
2457 }
2458 else
2459 {
2460 uint64_t tmp = a;
2461
2462 uint64_t result = a + safe_abs64(b);
2463
2464 if (result >= tmp)
2465 return result;
2466 }
2467
2468 safe_math_fail("safe_math_fail safe_sub_uint64_int32");
2469 }
2470
2471 static inline bool check_sub_uint64_int32(uint64_t a, int32_t b, uint64_t* ret)
2472 {
2473 if (b >= 0)
2474 {
2475 if ((uint64_t)b <= a)
2476 {
2477 *ret = (uint64_t)(a - (uint64_t)b);
2478 return true;
2479 }
2480 }
2481 else
2482 {
2483 uint64_t tmp = a;
2484
2485 uint64_t result = a + safe_abs64(b);
2486
2487 if (result >= tmp)
2488 {
2489 *ret = result;
2490 return true;
2491 }
2492 }
2493
2494 return false;
2495 }
2496
2497 static inline uint64_t safe_sub_uint64_uint32(uint64_t a, uint32_t b)
2498 {
2499 uint64_t tmp = a - b;
2500
2501 if (tmp <= a)
2502 return tmp;
2503
2504 safe_math_fail("safe_math_fail safe_sub_uint64_uint32");
2505 }
2506
2507 static inline bool check_sub_uint64_uint32(uint64_t a, uint32_t b, uint64_t* ret)
2508 {
2509 uint64_t tmp = a - b;
2510 *ret = tmp;
2511 return (tmp <= a);
2512 }
2513
2514 static inline uint64_t safe_sub_uint64_int64(uint64_t a, int64_t b)
2515 {
2516 uint64_t result = 0;
2517
2518
2519 if (b >= 0)
2520 {
2521 if ((uint64_t)b <= a)
2522 {
2523 return (a - (uint64_t)b);
2524 }
2525 }
2526 else
2527 {
2528
2529 result = a + safe_abs64(b);
2530
2531 if (result >= a)
2532 return result;
2533 }
2534
2535 safe_math_fail("safe_math_fail safe_sub_uint64_int64");
2536 }
2537
2538 static inline bool check_sub_uint64_int64(uint64_t a, int64_t b, uint64_t* ret)
2539 {
2540 uint64_t result = 0;
2541
2542
2543 if (b >= 0)
2544 {
2545 if ((uint64_t)b <= a)
2546 {
2547 *ret = (a - (uint64_t)b);
2548 return true;
2549 }
2550 }
2551 else
2552 {
2553
2554 result = a + safe_abs64(b);
2555
2556 if (result >= a)
2557 {
2558 *ret = result;
2559 return true;
2560 }
2561 }
2562
2563 return false;
2564 }
2565
2566 static inline uint64_t safe_sub_uint64_uint64(uint64_t a, uint64_t b)
2567 {
2568 uint64_t tmp = a - b;
2569
2570 if (tmp <= a)
2571 return tmp;
2572
2573 safe_math_fail("safe_math_fail safe_sub_uint64_uint64");
2574 }
2575
2576 static inline bool check_sub_uint64_uint64(uint64_t a, uint64_t b, uint64_t* ret)
2577 {
2578 uint64_t tmp = a - b;
2579 *ret = tmp;
2580 return (tmp <= a);
2581 }
2582
2583 #ifdef __cplusplus
2584 }
2585 #endif
2586
2587 #endif