diff options
| author | Jacob Champion <jchampion@postgresql.org> | 2025-11-24 09:59:38 -0800 |
|---|---|---|
| committer | Jacob Champion <jchampion@postgresql.org> | 2025-11-24 09:59:38 -0800 |
| commit | 8934f2136cd82333fd148954a13a8ab01f7bd7ef (patch) | |
| tree | 3e92b92bb156dea504dcf76cd949d4b17998ea4a /src/include/common/int.h | |
| parent | f1881c7dd32cf5f429f6bd525b5cbacef3bb9c99 (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.h | 67 |
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. |
