diff options
author | Jeremy Evans <[email protected]> | 2025-01-08 08:49:51 -0800 |
---|---|---|
committer | <[email protected]> | 2025-01-08 08:49:51 -0800 |
commit | e0d600ec190c64aff76cfcbd6009cffb927da166 () | |
tree | 3ef2eba19dc6ab2269b8f0c9f3ccb303f24e2037 | |
parent | e728170043ab9afb0f064af2bcfcf6ca06f9573d (diff) |
Avoid opt_aset_with optimization inside multiple assignment
Previously, since the opt_aset_with optimization was introduced, use of the opt_aset_with optimization inside multiple assignment would result in a segfault or incorrect instructions. Fixes [Bug #21012] Co-authored-by: Nobuyoshi Nakada <[email protected]>
Notes: Merged: https://.com/ruby/ruby/pull/12528 Merged-By: jeremyevans <[email protected]>
-rw-r--r-- | compile.c | 6 | ||||
-rw-r--r-- | iseq.h | 1 | ||||
-rw-r--r-- | test/ruby/test_assignment.rb | 10 |
3 files changed, 16 insertions, 1 deletions
@@ -10240,7 +10240,8 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node /* optimization shortcut * obj["literal"] = value -> opt_aset_with(obj, "literal", value) */ - if (mid == idASET && !private_recv_p(node) && RNODE_ATTRASGN(node)->nd_args && nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 && (nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_FILE)) && ISEQ_COMPILE_DATA(iseq)->current_block == NULL && @@ -10793,7 +10794,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_MASGN:{ compile_massign(iseq, ret, node, popped); break; } @@ -119,6 +119,7 @@ struct iseq_compile_data { struct iseq_compile_data_storage *storage_current; } insn; bool in_rescue; int loopval_popped; /* used by NODE_BREAK */ int last_line; int label_no; @@ -248,6 +248,16 @@ class TestAssignment < Test::Unit::TestCase a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c]) end def test_assign_rescue a = raise rescue 2; assert_equal(2, a) a, b = raise rescue [3,4]; assert_equal([3, 4], [a, b]) |