overflow.h 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. /// @file
  2. /// @brief arithmetic overflow helpers
  3. /// @ingroup cgraph_utils
  4. ///
  5. /// Replace this with stdckdint.h when moving to C23.
  6. #pragma once
  7. #include <assert.h>
  8. #include <limits.h>
  9. #include <stdbool.h>
  10. #include <stddef.h>
  11. /** add two integers, checking for overflow
  12. *
  13. * @param a Operand 1
  14. * @param b Operand 2
  15. * @param res [out] Result on success
  16. * @return True if overflow would occur
  17. */
  18. static inline bool sadd_overflow(int a, int b, int *res) {
  19. assert(res != NULL);
  20. // delegate to hardware optimized implementations where possible
  21. #if defined(__clang__) && \
  22. (__clang_major__ > 3 || \
  23. (__clang_major__ == 3 && __clang_minor__ > 7)) // Clang ≥ 3.8
  24. return __builtin_sadd_overflow(a, b, res);
  25. #elif defined(__GNUC__) && __GNUC__ > 4 // GCC ≥ 5
  26. return __builtin_sadd_overflow(a, b, res);
  27. #endif
  28. if (a > 0 && INT_MAX - a < b) {
  29. return true;
  30. }
  31. if (a < 0 && INT_MIN - a > b) {
  32. return true;
  33. }
  34. *res = a + b;
  35. return false;
  36. }