Move rbimpl_size_add_overflow from gc.c to memory.h
This commit is contained in:
parent
b8c4af24f9
commit
99ff0224a5
Notes:
git
2025-01-02 16:03:26 +00:00
40
gc.c
40
gc.c
@ -480,39 +480,11 @@ rb_malloc_grow_capa(size_t current, size_t type_size)
|
||||
return new_capacity;
|
||||
}
|
||||
|
||||
static inline struct rbimpl_size_mul_overflow_tag
|
||||
size_add_overflow(size_t x, size_t y)
|
||||
{
|
||||
size_t z;
|
||||
bool p;
|
||||
#if 0
|
||||
|
||||
#elif defined(ckd_add)
|
||||
p = ckd_add(&z, x, y);
|
||||
|
||||
#elif __has_builtin(__builtin_add_overflow)
|
||||
p = __builtin_add_overflow(x, y, &z);
|
||||
|
||||
#elif defined(DSIZE_T)
|
||||
RB_GNUC_EXTENSION DSIZE_T dx = x;
|
||||
RB_GNUC_EXTENSION DSIZE_T dy = y;
|
||||
RB_GNUC_EXTENSION DSIZE_T dz = dx + dy;
|
||||
p = dz > SIZE_MAX;
|
||||
z = (size_t)dz;
|
||||
|
||||
#else
|
||||
z = x + y;
|
||||
p = z < y;
|
||||
|
||||
#endif
|
||||
return (struct rbimpl_size_mul_overflow_tag) { p, z, };
|
||||
}
|
||||
|
||||
static inline struct rbimpl_size_mul_overflow_tag
|
||||
size_mul_add_overflow(size_t x, size_t y, size_t z) /* x * y + z */
|
||||
{
|
||||
struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y);
|
||||
struct rbimpl_size_mul_overflow_tag u = size_add_overflow(t.right, z);
|
||||
struct rbimpl_size_mul_overflow_tag u = rbimpl_size_add_overflow(t.right, z);
|
||||
return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left, u.right };
|
||||
}
|
||||
|
||||
@ -521,7 +493,7 @@ size_mul_add_mul_overflow(size_t x, size_t y, size_t z, size_t w) /* x * y + z *
|
||||
{
|
||||
struct rbimpl_size_mul_overflow_tag t = rbimpl_size_mul_overflow(x, y);
|
||||
struct rbimpl_size_mul_overflow_tag u = rbimpl_size_mul_overflow(z, w);
|
||||
struct rbimpl_size_mul_overflow_tag v = size_add_overflow(t.right, u.right);
|
||||
struct rbimpl_size_mul_overflow_tag v = rbimpl_size_add_overflow(t.right, u.right);
|
||||
return (struct rbimpl_size_mul_overflow_tag) { t.left || u.left || v.left, v.right };
|
||||
}
|
||||
|
||||
@ -4590,6 +4562,14 @@ ruby_malloc_size_overflow(size_t count, size_t elsize)
|
||||
count, elsize);
|
||||
}
|
||||
|
||||
void
|
||||
ruby_malloc_add_size_overflow(size_t x, size_t y)
|
||||
{
|
||||
rb_raise(rb_eArgError,
|
||||
"malloc: possible integer overflow (%"PRIuSIZE"+%"PRIuSIZE")",
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void *ruby_xmalloc2_body(size_t n, size_t size);
|
||||
|
||||
void *
|
||||
|
@ -488,6 +488,18 @@ RBIMPL_ATTR_NORETURN()
|
||||
*/
|
||||
void ruby_malloc_size_overflow(size_t x, size_t y);
|
||||
|
||||
RBIMPL_ATTR_NORETURN()
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* This is an implementation detail. People don't use this directly.
|
||||
*
|
||||
* @param[in] x Arbitrary value.
|
||||
* @param[in] y Arbitrary value.
|
||||
* @exception rb_eArgError `x` + `y` would integer overflow.
|
||||
*/
|
||||
void ruby_malloc_add_size_overflow(size_t x, size_t y);
|
||||
|
||||
#ifdef HAVE_RB_GC_GUARDED_PTR_VAL
|
||||
volatile VALUE *rb_gc_guarded_ptr_val(volatile VALUE *ptr, VALUE val);
|
||||
#endif
|
||||
@ -635,6 +647,81 @@ rbimpl_size_mul_or_raise(size_t x, size_t y)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__DOXYGEN__)
|
||||
RBIMPL_ATTR_CONSTEXPR(CXX14)
|
||||
#elif RBIMPL_COMPILER_SINCE(GCC, 7, 0, 0)
|
||||
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70507 */
|
||||
#elif RBIMPL_COMPILER_SINCE(Clang, 7, 0, 0)
|
||||
RBIMPL_ATTR_CONSTEXPR(CXX14) /* https://bugs.llvm.org/show_bug.cgi?id=37633 */
|
||||
#endif
|
||||
RBIMPL_ATTR_CONST()
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* This is an implementation detail. People don't use this directly.
|
||||
*
|
||||
* @param[in] x Arbitrary value.
|
||||
* @param[in] y Arbitrary value.
|
||||
* @return `{ left, right }`, where `left` is whether there is an integer
|
||||
* overflow or not, and `right` is a (possibly overflowed) result
|
||||
* of `x` + `y`.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
static inline struct rbimpl_size_mul_overflow_tag
|
||||
rbimpl_size_add_overflow(size_t x, size_t y)
|
||||
{
|
||||
struct rbimpl_size_mul_overflow_tag ret = { false, 0, };
|
||||
|
||||
#if defined(ckd_add)
|
||||
ret.left = ckd_add(&ret.right, x, y);
|
||||
|
||||
#elif RBIMPL_HAS_BUILTIN(__builtin_add_overflow)
|
||||
ret.left = __builtin_add_overflow(x, y, &ret.right);
|
||||
|
||||
#elif defined(DSIZE_T)
|
||||
RB_GNUC_EXTENSION DSIZE_T dx = x;
|
||||
RB_GNUC_EXTENSION DSIZE_T dy = y;
|
||||
RB_GNUC_EXTENSION DSIZE_T dz = dx + dy;
|
||||
ret.left = dz > SIZE_MAX;
|
||||
ret.right = (size_t)dz;
|
||||
|
||||
#else
|
||||
ret.right = x + y;
|
||||
ret.left = ret.right < y;
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
* This is an implementation detail. People don't use this directly.
|
||||
*
|
||||
* @param[in] x Arbitrary value.
|
||||
* @param[in] y Arbitrary value.
|
||||
* @exception rb_eArgError Multiplication could integer overflow.
|
||||
* @return `x` + `y`.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
static inline size_t
|
||||
rbimpl_size_add_or_raise(size_t x, size_t y)
|
||||
{
|
||||
struct rbimpl_size_mul_overflow_tag size =
|
||||
rbimpl_size_add_overflow(x, y);
|
||||
|
||||
if (RB_LIKELY(!size.left)) {
|
||||
return size.right;
|
||||
}
|
||||
else {
|
||||
ruby_malloc_add_size_overflow(x, y);
|
||||
RBIMPL_UNREACHABLE_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an implementation detail of #RB_ALLOCV_N(). People don't use this
|
||||
* directly.
|
||||
|
Loading…
x
Reference in New Issue
Block a user