summaryrefslogtreecommitdiff
path: root/src/include/common/int.h
diff options
context:
space:
mode:
authorJacob Champion <jchampion@postgresql.org>2025-11-24 09:59:38 -0800
committerJacob Champion <jchampion@postgresql.org>2025-11-24 09:59:38 -0800
commit8934f2136cd82333fd148954a13a8ab01f7bd7ef (patch)
tree3e92b92bb156dea504dcf76cd949d4b17998ea4a /src/include/common/int.h
parentf1881c7dd32cf5f429f6bd525b5cbacef3bb9c99 (diff)
Add pg_add_size_overflow() and friends
Commit 600086f47 added (several bespoke copies of) size_t addition with overflow checks to libpq. Move this to common/int.h, along with its subtraction and multiplication counterparts. pg_neg_size_overflow() is intentionally omitted; I'm not sure we should add SSIZE_MAX to win32_port.h for the sake of a function with no callers. Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAOYmi%2B%3D%2BpqUd2MUitvgW1pAJuXgG_TKCVc3_Ek7pe8z9nkf%2BAg%40mail.gmail.com
Diffstat (limited to 'src/include/common/int.h')
-rw-r--r--src/include/common/int.h67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/include/common/int.h b/src/include/common/int.h
index 3973f13379d..435716b7906 100644
--- a/src/include/common/int.h
+++ b/src/include/common/int.h
@@ -601,6 +601,73 @@ pg_neg_u64_overflow(uint64 a, int64 *result)
#endif
}
+/*
+ * size_t
+ */
+static inline bool
+pg_add_size_overflow(size_t a, size_t b, size_t *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_add_overflow(a, b, result);
+#else
+ size_t res = a + b;
+
+ if (res < a)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = res;
+ return false;
+#endif
+}
+
+static inline bool
+pg_sub_size_overflow(size_t a, size_t b, size_t *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_sub_overflow(a, b, result);
+#else
+ if (b > a)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = a - b;
+ return false;
+#endif
+}
+
+static inline bool
+pg_mul_size_overflow(size_t a, size_t b, size_t *result)
+{
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
+ return __builtin_mul_overflow(a, b, result);
+#else
+ size_t res = a * b;
+
+ if (a != 0 && b != res / a)
+ {
+ *result = 0x5EED; /* to avoid spurious warnings */
+ return true;
+ }
+ *result = res;
+ return false;
+#endif
+}
+
+/*
+ * pg_neg_size_overflow is currently omitted, to avoid having to reason about
+ * the portability of SSIZE_MIN/_MAX before a use case exists.
+ */
+/*
+ * static inline bool
+ * pg_neg_size_overflow(size_t a, ssize_t *result)
+ * {
+ * ...
+ * }
+ */
+
/*------------------------------------------------------------------------
*
* Comparison routines for integer types.