diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | parse.y | 36 | ||||
-rw-r--r-- | test/ruby/test_syntax.rb | 6 |
3 files changed, 40 insertions, 8 deletions
@@ -1,3 +1,9 @@ +Wed Nov 26 17:25:45 2014 Nobuyoshi Nakada <[email protected]> + + * parse.y (f_label, f_kw, formal_argument_gen): ignore invalid + formal argument in keyword argument definition. + [ruby-dev:48742] [Bug #10545] + Wed Nov 26 15:32:06 2014 Koichi Sasada <[email protected]> * compile.c (iseq_set_sequence): use "nop" insn instead of @@ -411,6 +411,7 @@ static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*); #define new_args(f,o,r,p,t) new_args_gen(parser, (f),(o),(r),(p),(t)) static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID); #define new_args_tail(k,kr,b) new_args_tail_gen(parser, (k),(kr),(b)) +#define new_kw_arg(k) ((k) ? NEW_KW_ARG(0, (k)) : 0) static VALUE negate_lit(VALUE); static NODE *ret_args_gen(struct parser_params*,NODE*); @@ -4715,9 +4716,9 @@ f_arg : f_arg_item f_label : tLABEL { ID id = get_id($1); - arg_var(formal_argument(id)); + $$ = formal_argument(id); + arg_var($$); current_arg = id; - $$ = $1; } ; @@ -4726,7 +4727,7 @@ f_kw : f_label arg_value current_arg = 0; $$ = assignable($1, $2); /*%%%*/ - $$ = NEW_KW_ARG(0, $$); + $$ = new_kw_arg($$); /*% $$ = rb_assoc_new($$, $2); %*/ @@ -4736,7 +4737,7 @@ f_kw : f_label arg_value current_arg = 0; $$ = assignable($1, (NODE *)-1); /*%%%*/ - $$ = NEW_KW_ARG(0, $$); + $$ = new_kw_arg($$); /*% $$ = rb_assoc_new($$, 0); %*/ @@ -4747,7 +4748,7 @@ f_block_kw : f_label primary_value { $$ = assignable($1, $2); /*%%%*/ - $$ = NEW_KW_ARG(0, $$); + $$ = new_kw_arg($$); /*% $$ = rb_assoc_new($$, $2); %*/ @@ -4756,7 +4757,7 @@ f_block_kw : f_label primary_value { $$ = assignable($1, (NODE *)-1); /*%%%*/ - $$ = NEW_KW_ARG(0, $$); + $$ = new_kw_arg($$); /*% $$ = rb_assoc_new($$, 0); %*/ @@ -6746,10 +6747,29 @@ arg_ambiguous_gen(struct parser_params *parser, char c) static ID formal_argument_gen(struct parser_params *parser, ID lhs) { + switch (id_type(lhs)) { + case ID_LOCAL: + break; #ifndef RIPPER - if (!is_local_id(lhs)) - yyerror("formal argument must be local variable"); + case ID_CONST: + yyerror("formal argument cannot be a constant"); + return 0; + case ID_INSTANCE: + yyerror("formal argument cannot be an instance variable"); + return 0; + case ID_GLOBAL: + yyerror("formal argument cannot be a global variable"); + return 0; + case ID_CLASS: + yyerror("formal argument cannot be a class variable"); + return 0; +#else + default: + lhs = dispatch1(param_error, lhs); + ripper_error(); + return 0; #endif + } shadowing_lvar(lhs); return lhs; } diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 00e21606c6..d36cbb0638 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -530,6 +530,12 @@ eom assert_syntax_error(code, /def n "\u{2208}"; end/, bug10114) end + def test_bad_kwarg + bug10545 = '[ruby-dev:48742] [Bug #10545]' + src = 'def foo(A: a) end' + assert_syntax_error(src, /formal argument/, bug10545) + end + private def not_label(x) @result = x; @not_label ||= nil end |