patch 9.1.0976: Vim9: missing return statement with throw Commit: https://github.com/vim/vim/commit/ab9a8947d73c09981b966d3994f0a9298b8b5674 Author: Yegappan Lakshmanan <yegap...@yahoo.com> Date: Mon Dec 30 09:56:34 2024 +0100
patch 9.1.0976: Vim9: missing return statement with throw Problem: Vim9: missing return statement with throw (atitcreate) Solution: Treat a throw statement at the end of an if-else block as a return statement (Yegappan Lakshmanan) fixes: #16312 closes: #16338 Signed-off-by: Yegappan Lakshmanan <yegap...@yahoo.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 030ff833e..79bb9d821 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -550,6 +550,47 @@ def Test_not_missing_return() v9.CheckScriptSuccess(lines) enddef +" Test for an if-else block ending in a throw statement +def Test_if_else_with_throw() + var lines =<< trim END + def Ifelse_Throw1(): number + if false + return 1 + else + throw 'Error' + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + def Ifelse_Throw2(): number + if true + throw 'Error' + else + return 2 + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) + + lines =<< trim END + def Ifelse_Throw3(): number + if true + return 1 + elseif false + throw 'Error' + else + return 3 + endif + enddef + defcompile + END + v9.CheckScriptSuccess(lines) +enddef + def Test_return_bool() var lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c index ca353c28c..d4fd17e6c 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 976, /**/ 975, /**/ diff --git a/src/vim9cmds.c b/src/vim9cmds.c index c7fa60aa4..f8ebfb128 100644 --- a/src/vim9cmds.c +++ b/src/vim9cmds.c @@ -602,7 +602,9 @@ compile_elseif(char_u *arg, cctx_T *cctx) return NULL; } unwind_locals(cctx, scope->se_local_count, TRUE); - if (!cctx->ctx_had_return) + if (!cctx->ctx_had_return && !cctx->ctx_had_throw) + // the previous if block didn't end in a "return" or a "throw" + // statement. scope->se_u.se_if.is_had_return = FALSE; if (cctx->ctx_skip == SKIP_NOT) @@ -749,7 +751,9 @@ compile_else(char_u *arg, cctx_T *cctx) return NULL; } unwind_locals(cctx, scope->se_local_count, TRUE); - if (!cctx->ctx_had_return) + if (!cctx->ctx_had_return && !cctx->ctx_had_throw) + // the previous if block didn't end in a "return" or a "throw" + // statement. scope->se_u.se_if.is_had_return = FALSE; scope->se_u.se_if.is_seen_else = TRUE; @@ -821,7 +825,9 @@ compile_endif(char_u *arg, cctx_T *cctx) } ifscope = &scope->se_u.se_if; unwind_locals(cctx, scope->se_local_count, TRUE); - if (!cctx->ctx_had_return) + if (!cctx->ctx_had_return && !cctx->ctx_had_throw) + // the previous if block didn't end in a "return" or a "throw" + // statement. ifscope->is_had_return = FALSE; if (scope->se_u.se_if.is_if_label >= 0) diff --git a/src/vim9compile.c b/src/vim9compile.c index c8a50cf4c..a2dd77a44 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -4407,7 +4407,16 @@ compile_def_function_body( cctx->ctx_had_return ? "return" : "throw"); return FAIL; } - cctx->ctx_had_throw = FALSE; + + // When processing the end of an if-else block, don't clear the + // "ctx_had_throw" flag. If an if-else block ends in a "throw" + // statement, then it is considered to end in a "return" statement. + // The "ctx_had_throw" is cleared immediately after processing the + // if-else block ending statement. + // Otherwise, clear the "had_throw" flag. + if (ea.cmdidx != CMD_else && ea.cmdidx != CMD_elseif + && ea.cmdidx != CMD_endif) + cctx->ctx_had_throw = FALSE; p = skipwhite(p); if (ea.cmdidx != CMD_SIZE @@ -4474,13 +4483,16 @@ compile_def_function_body( case CMD_elseif: line = compile_elseif(p, cctx); cctx->ctx_had_return = FALSE; + cctx->ctx_had_throw = FALSE; break; case CMD_else: line = compile_else(p, cctx); cctx->ctx_had_return = FALSE; + cctx->ctx_had_throw = FALSE; break; case CMD_endif: line = compile_endif(p, cctx); + cctx->ctx_had_throw = FALSE; break; case CMD_while: @@ -4695,7 +4707,7 @@ compile_dfunc_scope_end_missing(cctx_T *cctx) } /* - * When compiling a def function, if it doesn not have an explicit return + * When compiling a def function, if it doesn't have an explicit return * statement, then generate a default return instruction. For an object * constructor, return the object. */ -- -- 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 vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1tSBdA-00DPZ4-JI%40256bit.org.