[Bug #21620] Fix strict aliasing in rb_managed_id_table_lookup

We cannot pass &ccs into rb_managed_id_table_lookup because rb_managed_id_table_lookup
takes in a VALUE*, so it violates strict aliasing in C. This causes segfaults
when compiling with LTO enabled.
This commit is contained in:
Peter Zhu 2025-10-02 18:39:24 -04:00
parent 52287c68ab
commit 14cdd88970
2 changed files with 14 additions and 6 deletions

View File

@ -2120,8 +2120,9 @@ vm_evict_cc(VALUE klass, VALUE cc_tbl, ID mid)
return;
}
struct rb_class_cc_entries *ccs = NULL;
rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs);
VALUE ccs_obj = 0;
rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj);
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj;
if (!ccs || !METHOD_ENTRY_INVALIDATED(ccs->cme)) {
// Another ractor replaced that entry while we were waiting on the VM lock.
@ -2182,7 +2183,11 @@ vm_populate_cc(VALUE klass, const struct rb_callinfo * const ci, ID mid)
if (ccs == NULL) {
VM_ASSERT(cc_tbl);
if (!LIKELY(rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs))) {
VALUE ccs_obj;
if (UNLIKELY(rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj))) {
ccs = (struct rb_class_cc_entries *)ccs_obj;
}
else {
// TODO: required?
ccs = vm_ccs_create(klass, cc_tbl, mid, cme);
}
@ -2217,7 +2222,9 @@ retry:
// CCS data is keyed on method id, so we don't need the method id
// for doing comparisons in the `for` loop below.
if (rb_managed_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
VALUE ccs_obj;
if (rb_managed_id_table_lookup(cc_tbl, mid, &ccs_obj)) {
ccs = (struct rb_class_cc_entries *)ccs_obj;
const int ccs_len = ccs->len;
if (UNLIKELY(METHOD_ENTRY_INVALIDATED(ccs->cme))) {

View File

@ -195,8 +195,9 @@ rb_vm_ccs_invalidate_and_free(struct rb_class_cc_entries *ccs)
void
rb_vm_cc_table_delete(VALUE table, ID mid)
{
struct rb_class_cc_entries *ccs;
if (rb_managed_id_table_lookup(table, mid, (VALUE *)&ccs)) {
VALUE ccs_obj;
if (rb_managed_id_table_lookup(table, mid, &ccs_obj)) {
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_obj;
rb_managed_id_table_delete(table, mid);
rb_vm_ccs_invalidate_and_free(ccs);
}