Undefine the alloc function for T_DATA classes

which have not undefined or redefined it.

When a `T_DATA` object is created whose class has not undefined or
redefined the alloc function, the alloc function now gets undefined by
Data_Wrap_Struct et al. Optionally, a future release may also warn
that this being done.

This should help developers of C extensions to meet the requirements
explained in "doc/extension.rdoc". Without a check like this, there is
no easy way for an author of a C extension to see where they have made
a mistake.
This commit is contained in:
Mike Dalessio 2021-05-26 01:38:31 -04:00 committed by Nobuyoshi Nakada
parent 6963f8f743
commit e8e3b7a0e2
Notes: git 2021-08-20 08:30:35 +09:00

15
gc.c
View File

@ -2749,11 +2749,22 @@ rb_class_allocate_instance(VALUE klass)
return obj;
}
static inline void
rb_data_object_check(VALUE klass)
{
if (klass != rb_cObject && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) {
rb_undef_alloc_func(klass);
#if 0 /* TODO: enable at the next release */
rb_warn("undefining the allocator of T_DATA class %"PRIsVALUE, klass);
#endif
}
}
VALUE
rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
{
RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1);
if (klass) Check_Type(klass, T_CLASS);
if (klass) rb_data_object_check(klass);
return newobj_of(klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, FALSE, sizeof(RVALUE));
}
@ -2769,7 +2780,7 @@ VALUE
rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type)
{
RUBY_ASSERT_ALWAYS(type);
if (klass) Check_Type(klass, T_CLASS);
if (klass) rb_data_object_check(klass);
return newobj_of(klass, T_DATA, (VALUE)type, (VALUE)1, (VALUE)datap, type->flags & RUBY_FL_WB_PROTECTED, sizeof(RVALUE));
}