From 28bf649a5732ffe5a47951b5e437b765cebc5b38 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 3 Mar 2022 15:11:20 +0000 Subject: [PATCH] patch 8.2.4499: Vim9: at the script level declarations leak to next block Problem: Vim9: at the script level declarations leak from try block to catch and finally block. Solution: End the block and start a new one. (closes #9883) --- src/ex_eval.c | 19 +++++++++++++++++++ src/testdir/test_vim9_script.vim | 24 ++++++++++++++++++++++++ src/version.c | 2 ++ 3 files changed, 45 insertions(+) diff --git a/src/ex_eval.c b/src/ex_eval.c index ab3079862..e3c544b89 100644 --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -1827,6 +1827,16 @@ ex_catch(exarg_T *eap) cstack->cs_flags[idx] |= CSF_ACTIVE | CSF_CAUGHT; did_emsg = got_int = did_throw = FALSE; catch_exception((except_T *)cstack->cs_exception[idx]); + + if (cstack->cs_idx >= 0 + && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) + { + // Variables declared in the previous block can no longer be + // used. + leave_block(cstack); + enter_block(cstack); + } + // It's mandatory that the current exception is stored in the cstack // so that it can be discarded at the next ":catch", ":finally", or // ":endtry" or when the catch clause is left by a ":continue", @@ -1930,6 +1940,15 @@ ex_finally(exarg_T *eap) */ cleanup_conditionals(cstack, CSF_TRY, FALSE); + if (cstack->cs_idx >= 0 + && (cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) + { + // Variables declared in the previous block can no longer be + // used. + leave_block(cstack); + enter_block(cstack); + } + /* * Make did_emsg, got_int, did_throw pending. If set, they overrule * a pending ":continue", ":break", ":return", or ":finish". Then diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 3c3434d14..68178cfc6 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -763,6 +763,30 @@ def Test_try_catch_throw() v9.CheckDefAndScriptSuccess(lines) enddef +def Test_try_var_decl() + var lines =<< trim END + vim9script + try + var in_try = 1 + assert_equal(1, get(s:, 'in_try', -1)) + throw "getout" + catch + var in_catch = 2 + assert_equal(-1, get(s:, 'in_try', -1)) + assert_equal(2, get(s:, 'in_catch', -1)) + finally + var in_finally = 3 + assert_equal(-1, get(s:, 'in_try', -1)) + assert_equal(-1, get(s:, 'in_catch', -1)) + assert_equal(3, get(s:, 'in_finally', -1)) + endtry + assert_equal(-1, get(s:, 'in_try', -1)) + assert_equal(-1, get(s:, 'in_catch', -1)) + assert_equal(-1, get(s:, 'in_finally', -1)) + END + v9.CheckScriptSuccess(lines) +enddef + def Test_try_ends_in_return() var lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c index 6131427f8..c6a9f73d2 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4499, /**/ 4498, /**/ -- 2.40.0