parse.y: fix invalid keyword argument

* parse.y (f_label, f_kw, formal_argument_gen): ignore invalid
  formal argument in keyword argument definition.
  [ruby-dev:48742] [Bug #10545]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-11-26 08:25:48 +00:00
parent c7855be25c
commit eab191040e
3 changed files with 40 additions and 8 deletions

View File

@ -1,3 +1,9 @@
Wed Nov 26 17:25:45 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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 <ko1@atdot.net> Wed Nov 26 15:32:06 2014 Koichi Sasada <ko1@atdot.net>
* compile.c (iseq_set_sequence): use "nop" insn instead of * compile.c (iseq_set_sequence): use "nop" insn instead of

36
parse.y
View File

@ -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)) #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); 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_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 VALUE negate_lit(VALUE);
static NODE *ret_args_gen(struct parser_params*,NODE*); static NODE *ret_args_gen(struct parser_params*,NODE*);
@ -4715,9 +4716,9 @@ f_arg : f_arg_item
f_label : tLABEL f_label : tLABEL
{ {
ID id = get_id($1); ID id = get_id($1);
arg_var(formal_argument(id)); $$ = formal_argument(id);
arg_var($$);
current_arg = id; current_arg = id;
$$ = $1;
} }
; ;
@ -4726,7 +4727,7 @@ f_kw : f_label arg_value
current_arg = 0; current_arg = 0;
$$ = assignable($1, $2); $$ = assignable($1, $2);
/*%%%*/ /*%%%*/
$$ = NEW_KW_ARG(0, $$); $$ = new_kw_arg($$);
/*% /*%
$$ = rb_assoc_new($$, $2); $$ = rb_assoc_new($$, $2);
%*/ %*/
@ -4736,7 +4737,7 @@ f_kw : f_label arg_value
current_arg = 0; current_arg = 0;
$$ = assignable($1, (NODE *)-1); $$ = assignable($1, (NODE *)-1);
/*%%%*/ /*%%%*/
$$ = NEW_KW_ARG(0, $$); $$ = new_kw_arg($$);
/*% /*%
$$ = rb_assoc_new($$, 0); $$ = rb_assoc_new($$, 0);
%*/ %*/
@ -4747,7 +4748,7 @@ f_block_kw : f_label primary_value
{ {
$$ = assignable($1, $2); $$ = assignable($1, $2);
/*%%%*/ /*%%%*/
$$ = NEW_KW_ARG(0, $$); $$ = new_kw_arg($$);
/*% /*%
$$ = rb_assoc_new($$, $2); $$ = rb_assoc_new($$, $2);
%*/ %*/
@ -4756,7 +4757,7 @@ f_block_kw : f_label primary_value
{ {
$$ = assignable($1, (NODE *)-1); $$ = assignable($1, (NODE *)-1);
/*%%%*/ /*%%%*/
$$ = NEW_KW_ARG(0, $$); $$ = new_kw_arg($$);
/*% /*%
$$ = rb_assoc_new($$, 0); $$ = rb_assoc_new($$, 0);
%*/ %*/
@ -6746,10 +6747,29 @@ arg_ambiguous_gen(struct parser_params *parser, char c)
static ID static ID
formal_argument_gen(struct parser_params *parser, ID lhs) formal_argument_gen(struct parser_params *parser, ID lhs)
{ {
switch (id_type(lhs)) {
case ID_LOCAL:
break;
#ifndef RIPPER #ifndef RIPPER
if (!is_local_id(lhs)) case ID_CONST:
yyerror("formal argument must be local variable"); 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 #endif
}
shadowing_lvar(lhs); shadowing_lvar(lhs);
return lhs; return lhs;
} }

View File

@ -530,6 +530,12 @@ eom
assert_syntax_error(code, /def n "\u{2208}"; end/, bug10114) assert_syntax_error(code, /def n "\u{2208}"; end/, bug10114)
end 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 private
def not_label(x) @result = x; @not_label ||= nil end def not_label(x) @result = x; @not_label ||= nil end