From 6462c1a042fec4017f7e3bf2c13ec6a29efd23d6 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 14 Mar 2023 03:42:47 +0900 Subject: `Hash#dup` for kwsplat arguments On `f(*a, **kw)` method calls, a rest keyword parameter is identically same Hash object is passed and it should make `#dup`ed Hahs. fix https://bugs.ruby-lang.org/issues/19526 --- compile.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 8aa2228c53..08d21d760e 100644 --- a/compile.c +++ b/compile.c @@ -5789,6 +5789,16 @@ check_keyword(const NODE *node) } #endif +static bool +keyword_node_single_splat_p(NODE *kwnode) +{ + RUBY_ASSERT(keyword_node_p(kwnode)); + + NODE *node = kwnode->nd_head; + return node->nd_head == NULL && + node->nd_next->nd_next == NULL; +} + static int setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, int dup_rest, unsigned int *flag_ptr, struct rb_callinfo_kwarg **kwarg_ptr) @@ -5881,7 +5891,9 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, if (kwnode) { // f(*a, k:1) *flag_ptr |= VM_CALL_KW_SPLAT; - *flag_ptr |= VM_CALL_KW_SPLAT_MUT; + if (!keyword_node_single_splat_p(kwnode)) { + *flag_ptr |= VM_CALL_KW_SPLAT_MUT; + } compile_hash(iseq, args, kwnode, TRUE, FALSE); argc += 1; } -- cgit v1.2.1