summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-29 16:51:19 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-01-29 16:51:19 +0000
commit7c6feec335827d3e4da1eea89e639fa417158a0a (patch)
tree10540fe55f07c1120f3fbf9c744d47fc418e4e85
parent0d836d908d15a7f66ab72d44ad264ff721731101 (diff)
* parse.y (top_compstmt, top_stmts, top_stmt): prohibit BEGIN {} in
non-toplevel scope. [ruby-core:21657] * test/ruby/test_beginendblock.rb (test_begininclass): add a test for above. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@21876 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--parse.y92
-rw-r--r--test/ruby/test_beginendblock.rb6
3 files changed, 83 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 38656766f8..2ffc52f999 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Fri Jan 30 01:39:27 2009 Yusuke Endoh <mame@tsg.ne.jp>
+
+ * parse.y (top_compstmt, top_stmts, top_stmt): prohibit BEGIN {} in
+ non-toplevel scope. [ruby-core:21657]
+
+ * test/ruby/test_beginendblock.rb (test_begininclass): add a test for
+ above.
+
Wed Jan 28 22:51:12 2009 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/zlib/zlib.c (zstream_run): desperately guard the variable.
diff --git a/parse.y b/parse.y
index 0d34ecbca3..0ebfc37a60 100644
--- a/parse.y
+++ b/parse.y
@@ -667,6 +667,7 @@ static void token_info_pop(struct parser_params*, const char *token);
%type <node> string_contents xstring_contents string_content
%type <node> words qwords word_list qword_list word
%type <node> literal numeric dsym cpath
+%type <node> top_compstmt top_stmts top_stmt
%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
%type <node> expr_value arg_value primary_value
%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
@@ -768,7 +769,7 @@ program : {
/*%
%*/
}
- compstmt
+ top_compstmt
{
/*%%%*/
if ($2 && !compile_for_eval) {
@@ -791,6 +792,73 @@ program : {
}
;
+top_compstmt : top_stmts opt_terms
+ {
+ /*%%%*/
+ void_stmts($1);
+ fixup_nodes(&deferred_nodes);
+ /*%
+ %*/
+ $$ = $1;
+ }
+ ;
+
+top_stmts : none
+ {
+ /*%%%*/
+ $$ = NEW_BEGIN(0);
+ /*%
+ $$ = dispatch2(stmts_add, dispatch0(stmts_new),
+ dispatch0(void_stmt));
+ %*/
+ }
+ | top_stmt
+ {
+ /*%%%*/
+ $$ = newline_node($1);
+ /*%
+ $$ = dispatch2(stmts_add, dispatch0(stmts_new), $1);
+ %*/
+ }
+ | top_stmts terms top_stmt
+ {
+ /*%%%*/
+ $$ = block_append($1, newline_node($3));
+ /*%
+ $$ = dispatch2(stmts_add, $1, $3);
+ %*/
+ }
+ | error top_stmt
+ {
+ $$ = remove_begin($2);
+ }
+ ;
+
+top_stmt : stmt
+ | keyword_BEGIN
+ {
+ if (in_def || in_single) {
+ yyerror("BEGIN in method");
+ }
+ /*%%%*/
+ /* local_push(0); */
+ /*%
+ %*/
+ }
+ '{' top_compstmt '}'
+ {
+ /*%%%*/
+ ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
+ $4);
+ /* NEW_PREEXE($4)); */
+ /* local_pop(); */
+ $$ = NEW_BEGIN(0);
+ /*%
+ $$ = dispatch1(BEGIN, $4);
+ %*/
+ }
+ ;
+
bodystmt : compstmt
opt_rescue
opt_else
@@ -964,28 +1032,6 @@ stmt : keyword_alias fitem {lex_state = EXPR_FNAME;} fitem
$$ = dispatch2(rescue_mod, $3, $1);
%*/
}
- | keyword_BEGIN
- {
- if (in_def || in_single) {
- yyerror("BEGIN in method");
- }
- /*%%%*/
- /* local_push(0); */
- /*%
- %*/
- }
- '{' compstmt '}'
- {
- /*%%%*/
- ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
- $4);
- /* NEW_PREEXE($4)); */
- /* local_pop(); */
- $$ = NEW_BEGIN(0);
- /*%
- $$ = dispatch1(BEGIN, $4);
- %*/
- }
| keyword_END '{' compstmt '}'
{
if (in_def || in_single) {
diff --git a/test/ruby/test_beginendblock.rb b/test/ruby/test_beginendblock.rb
index 463ebd94b6..4cfcbb01de 100644
--- a/test/ruby/test_beginendblock.rb
+++ b/test/ruby/test_beginendblock.rb
@@ -41,6 +41,12 @@ class TestBeginEndBlock < Test::Unit::TestCase
end
end
+ def test_begininclass
+ assert_raise(SyntaxError) do
+ eval("class TestBeginEndBlock; BEGIN {}; end")
+ end
+ end
+
def test_endblockwarn
ruby = EnvUtil.rubybin
# Use Tempfile to create temporary file path.