summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/compiler.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/include/compiler.h b/include/compiler.h
index 545a72e5..8e8a658d 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,12 +198,46 @@
#error shim has no cache_invalidate() implementation for this compiler
#endif /* __GNUC__ */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define GNUC_PREREQ(maj, min) 0
+#endif
+
+#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
+#define CLANG_PREREQ(maj, min) \
+ ((__clang_major__ > (maj)) || \
+ (__clang_major__ == (maj) && __clang_minor__ >= (min)))
+#else
+#define CLANG_PREREQ(maj, min) 0
+#endif
+
+#if GNUC_PREREQ(5, 1) || CLANG_PREREQ(3, 8)
#define checked_add(addend0, addend1, sum) \
__builtin_add_overflow(addend0, addend1, sum)
#define checked_sub(minuend, subtrahend, difference) \
__builtin_sub_overflow(minuend, subtrahend, difference)
#define checked_mul(factor0, factor1, product) \
__builtin_mul_overflow(factor0, factor1, product)
+#else
+#define checked_add(a0, a1, s) \
+ ({ \
+ (*s) = ((a0) + (a1)); \
+ 0; \
+ })
+#define checked_sub(s0, s1, d) \
+ ({ \
+ (*d) = ((s0) - (s1)); \
+ 0; \
+ })
+#define checked_mul(f0, f1, p) \
+ ({ \
+ (*p) = ((f0) * (f1)); \
+ 0; \
+ })
+#endif
+
#define checked_div(dividend, divisor, quotient) \
({ \
bool _ret = True; \