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 -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202108071128.177BS2wA1815491%40masaka.moolenaar.net.