aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-23 01:28:25 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-23 01:28:25 +0200
commit8c8467a824c950fd1094e46a74c1f57048e5f099 (patch)
treea2510527550ba3e15add02d86f199bac6dcf3351
parent8b16efb80d9a863641a0a7395204df038feeb56c (diff)
Add primitives for unsigned addition/multiplication with overflow
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--configure.ac5
-rw-r--r--include/util.h27
2 files changed, 32 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 2ec9674..d6c1612 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,11 @@ fi
##### additional checks #####
AX_COMPILE_CHECK_SIZEOF(time_t)
+AX_COMPILE_CHECK_SIZEOF(size_t)
+AX_COMPILE_CHECK_SIZEOF(short)
+AX_COMPILE_CHECK_SIZEOF(int)
+AX_COMPILE_CHECK_SIZEOF(long)
+AX_COMPILE_CHECK_SIZEOF(long long)
AC_CHECK_HEADERS([sys/xattr.h], [], [])
diff --git a/include/util.h b/include/util.h
index 99418f9..ae8c43c 100644
--- a/include/util.h
+++ b/include/util.h
@@ -11,6 +11,33 @@
#include <sys/types.h>
#include <stdint.h>
+#include <stddef.h>
+
+#if defined(__GNUC__) || defined(__clang__)
+#define UI_ADD_OV __builtin_uadd_overflow
+#define UL_ADD_OV __builtin_uaddl_overflow
+#define ULL_ADD_OV __builtin_uaddll_overflow
+
+#define UI_MUL_OV __builtin_umul_overflow
+#define UL_MUL_OV __builtin_umull_overflow
+#define ULL_MUL_OV __builtin_umulll_overflow
+#else
+#error Sorry, I do not know how to trap integer overflows with this compiler
+#endif
+
+#if SIZEOF_SIZE_T <= SIZEOF_INT
+#define SZ_ADD_OV UI_ADD_OV
+#define SZ_MUL_OV UI_MUL_OV
+#elif SIZEOF_SIZE_T == SIZEOF_LONG
+#define SZ_ADD_OV UL_ADD_OV
+#define SZ_MUL_OV UL_MUL_OV
+#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+#define SZ_ADD_OV ULL_ADD_OV
+#define SZ_MUL_OV ULL_MUL_OV
+#else
+#error Cannot determine maximum value of size_t
+#endif
+
/* layout structure for sparse files, indicating where the actual data is */
typedef struct sparse_map_t {