aboutsummaryrefslogtreecommitdiffstats
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-16 05:36:42 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-16 05:36:42 +0000
commit8c15f40acfd4171419d15b2516674a067d7d999f (patch)
treecb5a01be40ffc9f21e2eeae47d2967552d326b15 /parse.y
parent7a666c67664053df9e749cc81d17a2312881d436 (diff)
downloadruby-8c15f40acfd4171419d15b2516674a067d7d999f.tar.gz
parse.y: no return in class
* parse.y (k_return): prohibit return in class/module body except for singleton class. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60790 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y23
1 files changed, 20 insertions, 3 deletions
diff --git a/parse.y b/parse.y
index 120b935d39..c3756c52a3 100644
--- a/parse.y
+++ b/parse.y
@@ -243,6 +243,7 @@ struct parser_params {
unsigned int in_main: 1;
unsigned int in_kwarg: 1;
unsigned int in_def: 1;
+ unsigned int in_class: 1;
unsigned int token_seen: 1;
unsigned int token_info_enabled: 1;
# if WARN_PAST_SCOPE
@@ -299,6 +300,7 @@ static int parser_yyerror(struct parser_params*, const char*);
#define lpar_beg (parser->lex.lpar_beg)
#define brace_nest (parser->lex.brace_nest)
#define in_def (parser->in_def)
+#define in_class (parser->in_class)
#define in_main (parser->in_main)
#define in_defined (parser->in_defined)
#define tokenbuf (parser->tokenbuf)
@@ -1700,7 +1702,7 @@ command : fcall command_args %prec tLOWEST
$$ = dispatch1(yield, $2);
%*/
}
- | keyword_return call_args
+ | k_return call_args
{
/*%%%*/
$$ = NEW_RETURN(ret_args($2));
@@ -2737,7 +2739,7 @@ primary : literal
$$ = dispatch1(hash, escape_Qundef($2));
%*/
}
- | keyword_return
+ | k_return
{
/*%%%*/
$$ = NEW_RETURN(0);
@@ -2937,6 +2939,8 @@ primary : literal
{
if (in_def)
yyerror0("class definition in method body");
+ $<num>1 = in_class;
+ in_class = 1;
local_push(0);
/*%%%*/
$<num>$ = ruby_sourceline;
@@ -2956,11 +2960,13 @@ primary : literal
$$ = dispatch3(class, $2, $3, $5);
%*/
local_pop();
+ in_class = $<num>1 & 1;
}
| k_class tLSHFT expr
{
- $<num>$ = in_def;
+ $<num>$ = (in_class << 1) | in_def;
in_def = 0;
+ in_class = 0;
local_push(0);
}
term
@@ -2978,11 +2984,14 @@ primary : literal
%*/
local_pop();
in_def = $<num>4 & 1;
+ in_class = ($<num>4 >> 1) & 1;
}
| k_module cpath
{
if (in_def)
yyerror0("module definition in method body");
+ $<num>1 = in_class;
+ in_class = 1;
local_push(0);
/*%%%*/
$<num>$ = ruby_sourceline;
@@ -3002,6 +3011,7 @@ primary : literal
$$ = dispatch2(module, $2, $4);
%*/
local_pop();
+ in_class = $<num>1 & 1;
}
| k_def fname
{
@@ -3184,6 +3194,13 @@ k_end : keyword_end
}
;
+k_return : keyword_return
+ {
+ if (in_class && !in_def && !dyna_in_block())
+ yyerror0("Invalid return in class/module body");
+ }
+ ;
+
then : term
/*%c%*/
/*%c