mirror of
https://github.com/postgres/postgres.git
synced 2026-01-27 21:43:08 +03:00
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
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user