From 7c6feec335827d3e4da1eea89e639fa417158a0a Mon Sep 17 00:00:00 2001 From: mame Date: Thu, 29 Jan 2009 16:51:19 +0000 Subject: * 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 --- ChangeLog | 8 ++++ parse.y | 92 ++++++++++++++++++++++++++++++----------- test/ruby/test_beginendblock.rb | 6 +++ 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 + + * 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 * 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 string_contents xstring_contents string_content %type words qwords word_list qword_list word %type literal numeric dsym cpath +%type top_compstmt top_stmts top_stmt %type bodystmt compstmt stmts stmt expr arg primary command command_call method_call %type expr_value arg_value primary_value %type 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. -- cgit v1.2.3