6daba0
From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001
6daba0
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
6daba0
Date: Thu, 5 Aug 2021 20:09:25 +0900
6daba0
Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062]
6daba0
6daba0
---
6daba0
 vm_eval.c       |  4 +++-
6daba0
 vm_insnhelper.c |  7 +++++--
6daba0
 vm_method.c     | 41 ++++++++++++++++++++++++++---------------
6daba0
 3 files changed, 34 insertions(+), 18 deletions(-)
6daba0
6daba0
diff --git a/vm_eval.c b/vm_eval.c
6daba0
index 6d4b5c3c0b28..7ce9f157e671 100644
6daba0
--- a/vm_eval.c
6daba0
+++ b/vm_eval.c
6daba0
@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
6daba0
     {
6daba0
         struct rb_class_cc_entries *ccs;
6daba0
         struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
+        VALUE ccs_data;
6daba0
 
6daba0
-        if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) {
6daba0
+        if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
6daba0
             // ok
6daba0
+            ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
         }
6daba0
         else {
6daba0
             ccs = vm_ccs_create(klass, cme);
6daba0
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
6daba0
index 14928b2afe8e..e186376b24d7 100644
6daba0
--- a/vm_insnhelper.c
6daba0
+++ b/vm_insnhelper.c
6daba0
@@ -1637,9 +1637,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
6daba0
     const ID mid = vm_ci_mid(ci);
6daba0
     struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
     struct rb_class_cc_entries *ccs = NULL;
6daba0
+    VALUE ccs_data;
6daba0
 
6daba0
     if (cc_tbl) {
6daba0
-        if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
6daba0
+        if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
6daba0
+            ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
             const int ccs_len = ccs->len;
6daba0
             VM_ASSERT(vm_ccs_verify(ccs, mid, klass));
6daba0
 
6daba0
@@ -1706,8 +1708,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
6daba0
     if (ccs == NULL) {
6daba0
         VM_ASSERT(cc_tbl != NULL);
6daba0
 
6daba0
-        if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) {
6daba0
+        if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) {
6daba0
             // rb_callable_method_entry() prepares ccs.
6daba0
+            ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
         }
6daba0
         else {
6daba0
             // TODO: required?
6daba0
diff --git a/vm_method.c b/vm_method.c
6daba0
index 016dba1dbb18..1fd0bd57f7ca 100644
6daba0
--- a/vm_method.c
6daba0
+++ b/vm_method.c
6daba0
@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid)
6daba0
 {
6daba0
     struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
     if (cc_tbl) {
6daba0
-        const struct rb_class_cc_entries *ccs;
6daba0
+        VALUE ccs;
6daba0
         if (target_mid) {
6daba0
-            if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) {
6daba0
+            if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) {
6daba0
                 fprintf(stderr, "  [CCTB] %p\n", (void *)cc_tbl);
6daba0
-                vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL);
6daba0
+                vm_ccs_dump_i(target_mid, ccs, NULL);
6daba0
             }
6daba0
         }
6daba0
         else {
6daba0
@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
6daba0
     fprintf(stderr, "# vm_mtbl\n");
6daba0
     while (klass) {
6daba0
         rp_m("  -> ", klass);
6daba0
-        rb_method_entry_t *me;
6daba0
+        VALUE me;
6daba0
 
6daba0
         if (RCLASS_M_TBL(klass)) {
6daba0
             if (target_mid != 0) {
6daba0
-                if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) {
6daba0
+                if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) {
6daba0
                     rp_m("  [MTBL] ", me);
6daba0
                 }
6daba0
             }
6daba0
@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
6daba0
         }
6daba0
         if (RCLASS_CALLABLE_M_TBL(klass)) {
6daba0
             if (target_mid != 0) {
6daba0
-                if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) {
6daba0
+                if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) {
6daba0
                     rp_m("  [CM**] ", me);
6daba0
                 }
6daba0
             }
6daba0
@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
6daba0
         // check only current class
6daba0
 
6daba0
         struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
-        struct rb_class_cc_entries *ccs;
6daba0
+        VALUE ccs_data;
6daba0
 
6daba0
         // invalidate CCs
6daba0
-        if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
6daba0
+        if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
6daba0
+            struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
             rb_vm_ccs_free(ccs);
6daba0
             rb_id_table_delete(cc_tbl, mid);
6daba0
             RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
6daba0
@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
6daba0
         }
6daba0
         else {
6daba0
             rb_vm_t *vm = GET_VM();
6daba0
-            if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
6daba0
+            VALUE cme_data = (VALUE) cme;
6daba0
+            if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
6daba0
                 rb_id_table_delete(vm->negative_cme_table, mid);
6daba0
-                vm_me_invalidate_cache((rb_callable_method_entry_t *)cme);
6daba0
+                vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data);
6daba0
 
6daba0
                 RB_DEBUG_COUNTER_INC(cc_invalidate_negative);
6daba0
             }
6daba0
@@ -1023,6 +1025,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
6daba0
 {
6daba0
     struct rb_id_table *mtbl;
6daba0
     const rb_callable_method_entry_t *cme;
6daba0
+    VALUE cme_data;
6daba0
 
6daba0
     if (me) {
6daba0
         if (me->defined_class == 0) {
6daba0
@@ -1032,7 +1035,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
6daba0
 
6daba0
             mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
6daba0
 
6daba0
-            if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) {
6daba0
+            if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
6daba0
+                cme = (rb_callable_method_entry_t *)cme_data;
6daba0
                 RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
6daba0
                 VM_ASSERT(callable_method_entry_p(cme));
6daba0
                 VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
6daba0
@@ -1076,9 +1080,10 @@ cached_callable_method_entry(VALUE klass, ID mid)
6daba0
     ASSERT_vm_locking();
6daba0
 
6daba0
     struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
-    struct rb_class_cc_entries *ccs;
6daba0
+    VALUE ccs_data;
6daba0
 
6daba0
-    if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
6daba0
+    if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
6daba0
+        struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
         VM_ASSERT(vm_ccs_p(ccs));
6daba0
 
6daba0
         if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) {
6daba0
@@ -1104,12 +1109,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
6daba0
 
6daba0
     struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
6daba0
     struct rb_class_cc_entries *ccs;
6daba0
+    VALUE ccs_data;
6daba0
 
6daba0
     if (!cc_tbl) {
6daba0
         cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
6daba0
     }
6daba0
 
6daba0
-    if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
6daba0
+    if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
6daba0
+        ccs = (struct rb_class_cc_entries *)ccs_data;
6daba0
         VM_ASSERT(ccs->cme == cme);
6daba0
     }
6daba0
     else {
6daba0
@@ -1123,8 +1130,12 @@ negative_cme(ID mid)
6daba0
 {
6daba0
     rb_vm_t *vm = GET_VM();
6daba0
     const rb_callable_method_entry_t *cme;
6daba0
+    VALUE cme_data;
6daba0
 
6daba0
-    if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
6daba0
+    if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
6daba0
+        cme = (rb_callable_method_entry_t *)cme_data;
6daba0
+    }
6daba0
+    else {
6daba0
         cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL);
6daba0
         rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme);
6daba0
     }