summaryrefslogtreecommitdiff
path: root/include/compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/compat.h')
-rw-r--r--include/compat.h44
1 files changed, 27 insertions, 17 deletions
diff --git a/include/compat.h b/include/compat.h
index b2bb054..ee47ef9 100644
--- a/include/compat.h
+++ b/include/compat.h
@@ -9,26 +9,36 @@
#include "sqfs/predef.h"
-#if defined(__GNUC__) || defined(__clang__)
-# if defined(__GNUC__) && __GNUC__ < 5
-# if SIZEOF_SIZE_T <= SIZEOF_INT
-# define SZ_ADD_OV __builtin_uadd_overflow
-# define SZ_MUL_OV __builtin_umul_overflow
-# elif SIZEOF_SIZE_T == SIZEOF_LONG
-# define SZ_ADD_OV __builtin_uaddl_overflow
-# define SZ_MUL_OV __builtin_umull_overflow
-# elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
-# define SZ_ADD_OV __builtin_uaddll_overflow
-# define SZ_MUL_OV __builtin_umulll_overflow
-# else
-# error Cannot determine maximum value of size_t
-# endif
+#if defined(__GNUC__) && __GNUC__ >= 5
+# define SZ_ADD_OV __builtin_add_overflow
+# define SZ_MUL_OV __builtin_mul_overflow
+#elif defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5
+# if SIZEOF_SIZE_T <= SIZEOF_INT
+# define SZ_ADD_OV __builtin_uadd_overflow
+# define SZ_MUL_OV __builtin_umul_overflow
+# elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define SZ_ADD_OV __builtin_uaddl_overflow
+# define SZ_MUL_OV __builtin_umull_overflow
+# elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+# define SZ_ADD_OV __builtin_uaddll_overflow
+# define SZ_MUL_OV __builtin_umulll_overflow
# else
-# define SZ_ADD_OV __builtin_add_overflow
-# define SZ_MUL_OV __builtin_mul_overflow
+# error Cannot determine maximum value of size_t
# endif
#else
-# error I do not know how to trap integer overflows with this compiler
+static inline int _sz_add_overflow(size_t a, size_t b, size_t *res)
+{
+ *res = a + b;
+ return (*res < a) ? 1 : 0;
+}
+
+static inline int _sz_mul_overflow(size_t a, size_t b, size_t *res)
+{
+ *res = a * b;
+ return (b > 0 && (a > SIZE_MAX / b)) ? 1 : 0;
+}
+# define SZ_ADD_OV _sz_add_overflow
+# define SZ_MUL_OV _sz_mul_overflow
#endif
#if defined(_WIN32) || defined(__WINDOWS__)