To: vim_dev@googlegroups.com Subject: Patch 8.2.4542 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4542 Problem: Vim9: "break" inside try/catch not handled correctly. Solution: First jump to :endtry. (closes #9927) Files: src/vim9cmds.c, src/vim9.h, src/testdir/test_vim9_script.vim *** ../vim-8.2.4541/src/vim9cmds.c 2022-02-25 21:10:49.430029941 +0000 --- src/vim9cmds.c 2022-03-10 21:39:15.479562607 +0000 *************** *** 1206,1211 **** --- 1206,1212 ---- compile_break(char_u *arg, cctx_T *cctx) { scope_T *scope = cctx->ctx_scope; + int try_scopes = 0; endlabel_T **el; for (;;) *************** *** 1215,1230 **** emsg(_(e_break_without_while_or_for)); return NULL; } ! if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE) break; scope = scope->se_outer; } ! // Jump to the end of the FOR or WHILE loop. ! if (scope->se_type == FOR_SCOPE) ! el = &scope->se_u.se_for.fs_end_label; ! else ! el = &scope->se_u.se_while.ws_end_label; if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL) return FAIL; --- 1216,1244 ---- emsg(_(e_break_without_while_or_for)); return NULL; } ! if (scope->se_type == FOR_SCOPE) ! { ! el = &scope->se_u.se_for.fs_end_label; ! break; ! } ! if (scope->se_type == WHILE_SCOPE) ! { ! el = &scope->se_u.se_while.ws_end_label; break; + } + if (scope->se_type == TRY_SCOPE) + ++try_scopes; scope = scope->se_outer; } ! if (try_scopes > 0) ! // Inside one or more try/catch blocks we first need to jump to the ! // "finally" or "endtry" to cleanup. Then come to the next JUMP ! // intruction, which we don't know the index of yet. ! generate_TRYCONT(cctx, try_scopes, cctx->ctx_instr.ga_len + 1); ! ! // Jump to the end of the FOR or WHILE loop. The instruction index will be ! // filled in later. if (compile_jump_to_end(el, JUMP_ALWAYS, cctx) == FAIL) return FAIL; *** ../vim-8.2.4541/src/vim9.h 2022-03-08 13:18:10.809020782 +0000 --- src/vim9.h 2022-03-10 21:42:03.343071674 +0000 *************** *** 121,127 **** ISN_CATCH, // drop v:exception ISN_FINALLY, // start of :finally block ISN_ENDTRY, // take entry off from ec_trystack ! ISN_TRYCONT, // handle :continue inside a :try statement // more expression operations ISN_ADDLIST, // add two lists --- 121,127 ---- ISN_CATCH, // drop v:exception ISN_FINALLY, // start of :finally block ISN_ENDTRY, // take entry off from ec_trystack ! ISN_TRYCONT, // handle :continue or :break inside a :try statement // more expression operations ISN_ADDLIST, // add two lists *** ../vim-8.2.4541/src/testdir/test_vim9_script.vim 2022-03-06 14:51:19.058997629 +0000 --- src/testdir/test_vim9_script.vim 2022-03-10 21:44:58.422676396 +0000 *************** *** 907,912 **** --- 907,934 ---- unlet g:sequence enddef + def Test_break_in_try_in_for() + var lines =<< trim END + vim9script + def Ls(): list + var ls: list + for s in ['abc', 'def'] + for _ in [123, 456] + try + eval [][0] + catch + break + endtry + endfor + ls += [s] + endfor + return ls + enddef + assert_equal(['abc', 'def'], Ls()) + END + v9.CheckScriptSuccess(lines) + enddef + def Test_nocatch_return_in_try() # return in try block returns normally def ReturnInTry(): string *** ../vim-8.2.4541/src/version.c 2022-03-10 20:47:38.557606237 +0000 --- src/version.c 2022-03-10 21:40:11.755383421 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4542, /**/ -- hundred-and-one symptoms of being an internet addict: 204. You have learned not to fall asleep on your keyboard the hard way /// 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 ///