Skip to content

Commit 17e21d8

Browse files
committed
merge revision(s) fc33559: [Backport #20570]
clear `kw_flag` if given hash is nil https://bugs.ruby-lang.org/issues/20570 is caused I missed to clear the `kw_flag` even if `keyword_hash` is nil.
1 parent df8a08f commit 17e21d8

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

test/ruby/test_keyword.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4432,6 +4432,24 @@ def test_value_omission
44324432
assert_equal({one: 1, two: 2}, f.call(one:, two:))
44334433
end
44344434

4435+
def m_bug20570(*a, **nil)
4436+
a
4437+
end
4438+
4439+
def test_splat_arg_with_prohibited_keyword
4440+
assert_equal([], m_bug20570(*[]))
4441+
assert_equal([1], m_bug20570(*[1]))
4442+
assert_equal([1, 2], m_bug20570(*[1, 2]))
4443+
h = nil
4444+
assert_equal([], m_bug20570(*[], **h))
4445+
assert_equal([1], m_bug20570(*[1], **h))
4446+
assert_equal([1, 2], m_bug20570(*[1, 2], **h))
4447+
4448+
assert_equal([], m_bug20570(*[], **nil))
4449+
assert_equal([1], m_bug20570(*[1], **nil))
4450+
assert_equal([1, 2], m_bug20570(*[1, 2], **nil))
4451+
end
4452+
44354453
private def one
44364454
1
44374455
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 3
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 93
14+
#define RUBY_PATCHLEVEL 94
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

vm_args.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,10 @@ fill_keys_values(st_data_t key, st_data_t val, st_data_t ptr)
434434
static inline int
435435
ignore_keyword_hash_p(VALUE keyword_hash, const rb_iseq_t * const iseq, unsigned int * kw_flag, VALUE * converted_keyword_hash)
436436
{
437-
if (!RB_TYPE_P(keyword_hash, T_HASH)) {
437+
if (keyword_hash == Qnil) {
438+
goto ignore;
439+
}
440+
else if (!RB_TYPE_P(keyword_hash, T_HASH)) {
438441
keyword_hash = rb_to_hash_type(keyword_hash);
439442
}
440443

@@ -445,9 +448,17 @@ ignore_keyword_hash_p(VALUE keyword_hash, const rb_iseq_t * const iseq, unsigned
445448
keyword_hash = rb_hash_dup(keyword_hash);
446449
}
447450
*converted_keyword_hash = keyword_hash;
448-
return !(ISEQ_BODY(iseq)->param.flags.has_kw) &&
449-
!(ISEQ_BODY(iseq)->param.flags.has_kwrest) &&
450-
RHASH_EMPTY_P(keyword_hash);
451+
452+
if (!(ISEQ_BODY(iseq)->param.flags.has_kw) &&
453+
!(ISEQ_BODY(iseq)->param.flags.has_kwrest) &&
454+
RHASH_EMPTY_P(keyword_hash)) {
455+
ignore:
456+
*kw_flag &= ~(VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT);
457+
return 1;
458+
}
459+
else {
460+
return 0;
461+
}
451462
}
452463

453464
static VALUE
@@ -577,7 +588,6 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
577588
arg_rest_dup(args);
578589
rb_ary_pop(args->rest);
579590
given_argc--;
580-
kw_flag &= ~(VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT);
581591
}
582592
else {
583593
if (rest_last != converted_keyword_hash) {
@@ -608,7 +618,6 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
608618
if (ignore_keyword_hash_p(last_arg, iseq, &kw_flag, &converted_keyword_hash)) {
609619
args->argc--;
610620
given_argc--;
611-
kw_flag &= ~(VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT);
612621
}
613622
else {
614623
if (!(kw_flag & VM_CALL_KW_SPLAT_MUT)) {

0 commit comments

Comments
 (0)