summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-08-12 16:38:10 +0200
committerBram Moolenaar <Bram@vim.org>2020-08-12 16:38:10 +0200
commited677f5587af366f185f8922b7dde4a98c884328 (patch)
tree308cdbcd0ba766227d73ef1a15574ca9ff487f58
parent7c5ad34878a338f1db57337b5ca9f68c0c39424e (diff)
downloadvim-git-ed677f5587af366f185f8922b7dde4a98c884328.tar.gz
patch 8.2.1428: Vim9: :def function does not abort on nested function errorv8.2.1428
Problem: Vim9: :def function does not abort on nested function error. Solution: Check whether an error message was given. (closes #6691)
-rw-r--r--src/testdir/test_vim9_script.vim18
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c13
3 files changed, 29 insertions, 4 deletions
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index d30511c39..8742883e1 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1054,6 +1054,24 @@ def Test_throw_vimscript()
CheckScriptSuccess(lines)
enddef
+def Test_error_in_nested_function()
+ # an error in a nested :function aborts executin in the calling :def function
+ let lines =<< trim END
+ vim9script
+ def Func()
+ Error()
+ g:test_var = 1
+ enddef
+ func Error() abort
+ eval [][0]
+ endfunc
+ Func()
+ END
+ g:test_var = 0
+ CheckScriptFailure(lines, 'E684:')
+ assert_equal(0, g:test_var)
+enddef
+
def Test_cexpr_vimscript()
# only checks line continuation
set errorformat=File\ %f\ line\ %l
diff --git a/src/version.c b/src/version.c
index 63c9c3d30..46d027d14 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1428,
+/**/
1427,
/**/
1426,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index fed7fed0e..00adff385 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -505,6 +505,7 @@ call_ufunc(ufunc_T *ufunc, int argcount, ectx_T *ectx, isn_T *iptr)
funcexe_T funcexe;
int error;
int idx;
+ int called_emsg_before = called_emsg;
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
&& compile_def_function(ufunc, FALSE, NULL) == FAIL)
@@ -542,6 +543,9 @@ call_ufunc(ufunc_T *ufunc, int argcount, ectx_T *ectx, isn_T *iptr)
user_func_error(error, ufunc->uf_name);
return FAIL;
}
+ if (called_emsg > called_emsg_before)
+ // Error other than from calling the function itself.
+ return FAIL;
return OK;
}
@@ -670,10 +674,11 @@ store_var(char_u *name, typval_T *tv)
static int
call_eval_func(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
{
- int called_emsg_before = called_emsg;
+ int called_emsg_before = called_emsg;
+ int res;
- if (call_by_name(name, argcount, ectx, iptr) == FAIL
- && called_emsg == called_emsg_before)
+ res = call_by_name(name, argcount, ectx, iptr);
+ if (res == FAIL && called_emsg == called_emsg_before)
{
dictitem_T *v;
@@ -690,7 +695,7 @@ call_eval_func(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
}
return call_partial(&v->di_tv, argcount, ectx);
}
- return OK;
+ return res;
}
/*