diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 3fbf1bc32f..d9aa71e268 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -361,6 +361,35 @@ def Test_try_catch() endtry assert_equal(99, n) + var done = 'no' + if 0 + try | catch | endtry + else + done = 'yes' + endif + assert_equal('yes', done) + + done = 'no' + if 1 + done = 'yes' + else + try | catch | endtry + done = 'never' + endif + assert_equal('yes', done) + + if 1 + else + try | catch /pat/ | endtry + try | catch /pat/ + endtry + try + catch /pat/ | endtry + try + catch /pat/ + endtry + endif + try # string slice returns a string, not a number n = g:astring[3] diff --git a/src/version.c b/src/version.c index ceea2777f5..26c9d8bf8d 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2263, /**/ 2262, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index d44fe487c6..045061e1c8 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -6916,11 +6916,14 @@ compile_try(char_u *arg, cctx_T *cctx) if (try_scope == NULL) return NULL; - // "catch" is set when the first ":catch" is found. - // "finally" is set when ":finally" or ":endtry" is found - try_scope->se_u.se_try.ts_try_label = instr->ga_len; - if (generate_instr(cctx, ISN_TRY) == NULL) - return NULL; + if (cctx->ctx_skip != SKIP_YES) + { + // "catch" is set when the first ":catch" is found. + // "finally" is set when ":finally" or ":endtry" is found + try_scope->se_u.se_try.ts_try_label = instr->ga_len; + if (generate_instr(cctx, ISN_TRY) == NULL) + return NULL; + } // scope for the try block itself scope = new_scope(cctx, BLOCK_SCOPE); @@ -6959,20 +6962,23 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED) return NULL; } - // Jump from end of previous block to :finally or :endtry - if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label, - JUMP_ALWAYS, cctx) == FAIL) - return NULL; - - // End :try or :catch 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_catch == 0) - isn->isn_arg.try.try_catch = instr->ga_len; - if (scope->se_u.se_try.ts_catch_label != 0) + if (cctx->ctx_skip != SKIP_YES) { - // 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 = instr->ga_len; + // Jump from end of previous block to :finally or :endtry + if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label, + JUMP_ALWAYS, cctx) == FAIL) + return NULL; + + // End :try or :catch 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_catch == 0) + isn->isn_arg.try.try_catch = instr->ga_len; + 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 = instr->ga_len; + } } p = skipwhite(arg); @@ -7019,7 +7025,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED) return NULL; } - if (generate_instr(cctx, ISN_CATCH) == NULL) + if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL) return NULL; if (new_scope(cctx, BLOCK_SCOPE) == NULL) @@ -7097,33 +7103,37 @@ compile_endtry(char_u *arg, cctx_T *cctx) return NULL; } - isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; - if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0) + if (cctx->ctx_skip != SKIP_YES) { - emsg(_(e_missing_catch_or_finally)); - return NULL; - } + isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label; + if (isn->isn_arg.try.try_catch == 0 + && isn->isn_arg.try.try_finally == 0) + { + emsg(_(e_missing_catch_or_finally)); + return NULL; + } - // Fill in the "end" label in jumps at the end of the blocks, if not done - // by ":finally". - compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx); + // Fill in the "end" label in jumps at the end of the blocks, if not + // done by ":finally". + compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx); - // End :catch or :finally scope: set value in ISN_TRY instruction - if (isn->isn_arg.try.try_catch == 0) - isn->isn_arg.try.try_catch = instr->ga_len; - if (isn->isn_arg.try.try_finally == 0) - isn->isn_arg.try.try_finally = instr->ga_len; + // End :catch or :finally scope: set value in ISN_TRY instruction + if (isn->isn_arg.try.try_catch == 0) + isn->isn_arg.try.try_catch = instr->ga_len; + if (isn->isn_arg.try.try_finally == 0) + isn->isn_arg.try.try_finally = instr->ga_len; - if (scope->se_u.se_try.ts_catch_label != 0) - { - // Last 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 = instr->ga_len; + if (scope->se_u.se_try.ts_catch_label != 0) + { + // Last 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 = instr->ga_len; + } } compile_endblock(cctx); - if (generate_instr(cctx, ISN_ENDTRY) == NULL) + if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == NULL) return NULL; return arg; }