To: vim_dev@googlegroups.com Subject: Patch 8.2.3305 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3305 Problem: Vim9: :finally in skipped block not handled correctly. Solution: Check whether :finally is in a skipped block. (Naruhiko Nishino, closes #8724) Files: src/ex_eval.c, src/vim9compile.c, src/testdir/test_vim9_script.vim *** ../vim-8.2.3304/src/ex_eval.c 2021-08-05 20:39:59.346053681 +0200 --- src/ex_eval.c 2021-08-07 13:23:46.191591326 +0200 *************** *** 2018,2024 **** { idx = cstack->cs_idx; ! if (in_vim9script() && (cstack->cs_flags[idx] & (CSF_CATCH|CSF_FINALLY)) == 0) { // try/endtry without any catch or finally: give an error and --- 2018,2025 ---- { idx = cstack->cs_idx; ! // Check the flags only when not in a skipped block. ! if (!skip && in_vim9script() && (cstack->cs_flags[idx] & (CSF_CATCH|CSF_FINALLY)) == 0) { // try/endtry without any catch or finally: give an error and *** ../vim-8.2.3304/src/vim9compile.c 2021-08-05 22:48:08.524435481 +0200 --- src/vim9compile.c 2021-08-07 13:20:07.284048015 +0200 *************** *** 8569,8617 **** return NULL; } ! // End :catch or :finally scope: set value in ISN_TRY instruction ! isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; ! if (isn->isn_arg.try.try_ref->try_finally != 0) { ! emsg(_(e_finally_dup)); ! return NULL; ! } ! this_instr = instr->ga_len; #ifdef FEAT_PROFILE ! if (cctx->ctx_compile_type == CT_PROFILE ! && ((isn_T *)instr->ga_data)[this_instr - 1] ! .isn_type == ISN_PROF_START) ! { ! // jump to the profile start of the "finally" ! --this_instr; ! ! // jump to the profile end above it ! if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1] ! .isn_type == ISN_PROF_END) --this_instr; ! } #endif ! // Fill in the "end" label in jumps at the end of the blocks. ! compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, ! this_instr, cctx); ! ! // If there is no :catch then an exception jumps to :finally. ! if (isn->isn_arg.try.try_ref->try_catch == 0) ! isn->isn_arg.try.try_ref->try_catch = this_instr; ! isn->isn_arg.try.try_ref->try_finally = this_instr; ! if (scope->se_u.se_try.ts_catch_label != 0) ! { ! // Previous catch without match jumps here ! isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; ! isn->isn_arg.jump.jump_where = this_instr; ! scope->se_u.se_try.ts_catch_label = 0; ! } ! if (generate_instr(cctx, ISN_FINALLY) == NULL) ! return NULL; ! // TODO: set index in ts_finally_label jumps return arg; } --- 8569,8620 ---- return NULL; } ! if (cctx->ctx_skip != SKIP_YES) { ! // End :catch or :finally scope: set value in ISN_TRY instruction ! isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; ! if (isn->isn_arg.try.try_ref->try_finally != 0) ! { ! emsg(_(e_finally_dup)); ! return NULL; ! } ! this_instr = instr->ga_len; #ifdef FEAT_PROFILE ! if (cctx->ctx_compile_type == CT_PROFILE ! && ((isn_T *)instr->ga_data)[this_instr - 1] ! .isn_type == ISN_PROF_START) ! { ! // jump to the profile start of the "finally" --this_instr; ! ! // jump to the profile end above it ! if (this_instr > 0 && ((isn_T *)instr->ga_data)[this_instr - 1] ! .isn_type == ISN_PROF_END) ! --this_instr; ! } #endif ! // Fill in the "end" label in jumps at the end of the blocks. ! compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, ! this_instr, cctx); ! ! // If there is no :catch then an exception jumps to :finally. ! if (isn->isn_arg.try.try_ref->try_catch == 0) ! isn->isn_arg.try.try_ref->try_catch = this_instr; ! isn->isn_arg.try.try_ref->try_finally = this_instr; ! if (scope->se_u.se_try.ts_catch_label != 0) ! { ! // Previous catch without match jumps here ! isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label; ! isn->isn_arg.jump.jump_where = this_instr; ! scope->se_u.se_try.ts_catch_label = 0; ! } ! if (generate_instr(cctx, ISN_FINALLY) == NULL) ! return NULL; ! // TODO: set index in ts_finally_label jumps ! } return arg; } *** ../vim-8.2.3304/src/testdir/test_vim9_script.vim 2021-08-03 21:16:14.513239986 +0200 --- src/testdir/test_vim9_script.vim 2021-08-07 13:24:43.467466979 +0200 *************** *** 641,646 **** --- 641,660 ---- endtry END CheckScriptFailure(lines, 'E1032:') + + # skipping try-finally-endtry when try-finally-endtry is used in another block + lines =<< trim END + if v:true + try + finally + endtry + else + try + finally + endtry + endif + END + CheckDefAndScriptSuccess(lines) enddef def Test_try_in_catch() *** ../vim-8.2.3304/src/version.c 2021-08-07 13:08:42.465099997 +0200 --- src/version.c 2021-08-07 13:21:47.727842499 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3305, /**/ -- `When any government, or any church for that matter, undertakes to say to its subjects, "This you may not read, this you must not see, this you are forbidden to know," the end result is tyranny and oppression no matter how holy the motives' -- Robert A Heinlein, "If this goes on --" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///