summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2025-01-25 14:37:41 +0900
committernagachika <nagachika@ruby-lang.org>2025-01-25 14:37:41 +0900
commitf9adaab928dff8dd7ecd4c560c288300a3c74880 (patch)
tree3065afe42a3cd57f698c7bc120219f37317d0466 /compile.c
parent845763fdf370846938b86a062827b237313c924f (diff)
merge revision(s) e0d600ec190c64aff76cfcbd6009cffb927da166: [Backport #21012]
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 <nobu.nakada@gmail.com>
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/compile.c b/compile.c
index 13d25e4595..0452305923 100644
--- a/compile.c
+++ b/compile.c
@@ -9321,7 +9321,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) && node->nd_args &&
+ if (!ISEQ_COMPILE_DATA(iseq)->in_masgn &&
+ mid == idASET && !private_recv_p(node) && node->nd_args &&
nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 2 &&
nd_type_p(node->nd_args->nd_head, NODE_STR) &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
@@ -9519,7 +9520,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_MASGN:{
+ bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn;
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = true;
compile_massign(iseq, ret, node, popped);
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn;
break;
}