diff options
-rw-r--r-- | src/nvim/eval/userfunc.c | 18 | ||||
-rw-r--r-- | src/nvim/testdir/test_vimscript.vim | 11 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 1b80b22213..d5a19dd7b9 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -3347,9 +3347,13 @@ bool set_ref_in_previous_funccal(int copyID) { bool abort = false; - for (funccall_T *fc = previous_funccal; fc != NULL; fc = fc->caller) { - abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL); - abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL); + for (funccall_T *fc = previous_funccal; !abort && fc != NULL; + fc = fc->caller) { + fc->fc_copyID = copyID + 1; + abort = abort + || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL) + || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL) + || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL); } return abort; } @@ -3360,9 +3364,11 @@ static bool set_ref_in_funccal(funccall_T *fc, int copyID) if (fc->fc_copyID != copyID) { fc->fc_copyID = copyID; - abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); - abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); - abort = abort || set_ref_in_func(NULL, fc->func, copyID); + abort = abort + || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL) + || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL) + || set_ref_in_list(&fc->l_varlist, copyID, NULL) + || set_ref_in_func(NULL, fc->func, copyID); } return abort; } diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index d2f13ff072..3e2e1795dc 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -1409,6 +1409,17 @@ func Test_compound_assignment_operators() let @/ = '' endfunc +func! Test_funccall_garbage_collect() + func Func(x, ...) + call add(a:x, a:000) + endfunc + call Func([], []) + " Must not crash cause by invalid freeing + call test_garbagecollect_now() + call assert_true(v:true) + delfunc Func +endfunc + func Test_function_defined_line() if has('gui_running') " Can't catch the output of gvim. |