diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-03-10 21:53:44 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-03-10 21:53:44 +0000 |
commit | 873f8243f6feadec72d9bf6203e550cc1b66611a (patch) | |
tree | c6610edac88cf0c6d68295a542ddba9605b62a89 /src/vim9cmds.c | |
parent | e406ff87c86de9da2d02d0e5ebbbf5c5eac051a6 (diff) | |
download | vim-git-873f8243f6feadec72d9bf6203e550cc1b66611a.tar.gz |
patch 8.2.4542: Vim9: "break" inside try/catch not handled correctlyv8.2.4542
Problem: Vim9: "break" inside try/catch not handled correctly.
Solution: First jump to :endtry. (closes #9927)
Diffstat (limited to 'src/vim9cmds.c')
-rw-r--r-- | src/vim9cmds.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/vim9cmds.c b/src/vim9cmds.c index c49a48270..5a4464459 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -1206,6 +1206,7 @@ compile_continue(char_u *arg, cctx_T *cctx) compile_break(char_u *arg, cctx_T *cctx) { scope_T *scope = cctx->ctx_scope; + int try_scopes = 0; endlabel_T **el; for (;;) @@ -1215,16 +1216,29 @@ compile_break(char_u *arg, cctx_T *cctx) emsg(_(e_break_without_while_or_for)); return NULL; } - if (scope->se_type == FOR_SCOPE || scope->se_type == WHILE_SCOPE) + 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; } - // 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 (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; |