summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-03-22 21:00:09 +0100
committerBram Moolenaar <Bram@vim.org>2016-03-22 21:00:09 +0100
commite4eb6ff089e79e659acf33c17dd0fda7177de526 (patch)
tree910b326824ce60fea246dcf913735c61610b29d9
parent6c0e984f263fc1eef42c9b34a80eff1bceb8d05b (diff)
patch 7.4.1638v7.4.1638
Problem: When binding a function to a dict the reference count is wrong. Solution: Decrement dict reference count, only reference the function when actually making a copy. (Ken Takata)
-rw-r--r--src/eval.c10
-rw-r--r--src/testdir/test_partial.vim10
-rw-r--r--src/version.c2
3 files changed, 19 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c
index b2338331f5..d922e6aef9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -12019,6 +12019,7 @@ partial_free(partial_T *pt)
for (i = 0; i < pt->pt_argc; ++i)
clear_tv(&pt->pt_argv[i]);
vim_free(pt->pt_argv);
+ dict_unref(pt->pt_dict);
func_unref(pt->pt_name);
vim_free(pt->pt_name);
vim_free(pt);
@@ -21797,7 +21798,8 @@ handle_subscript(
selfdict = NULL;
if (rettv->v_type == VAR_FUNC)
{
- /* just a function: use selfdict */
+ /* Just a function: Take over the function name and use
+ * selfdict. */
pt->pt_name = rettv->vval.v_string;
}
else
@@ -21805,8 +21807,11 @@ handle_subscript(
partial_T *ret_pt = rettv->vval.v_partial;
int i;
- /* partial: use selfdict and copy args */
+ /* Partial: copy the function name, use selfdict and copy
+ * args. Can't take over name or args, the partial might
+ * be referenced elsewhere. */
pt->pt_name = vim_strsave(ret_pt->pt_name);
+ func_ref(pt->pt_name);
if (ret_pt->pt_argc > 0)
{
pt->pt_argv = (typval_T *)alloc(
@@ -21823,7 +21828,6 @@ handle_subscript(
}
partial_unref(ret_pt);
}
- func_ref(pt->pt_name);
rettv->v_type = VAR_PARTIAL;
rettv->vval.v_partial = pt;
}
diff --git a/src/testdir/test_partial.vim b/src/testdir/test_partial.vim
index 3764f221fc..f67bb41dd8 100644
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -170,3 +170,13 @@ func Test_partial_string()
let F = function('MyFunc', ['foo'], d)
call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
endfunc
+
+func Test_func_unref()
+ let obj = {}
+ function! obj.func() abort
+ endfunction
+ let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''')
+ call assert_true(exists('*{' . funcnumber . '}'))
+ unlet obj
+ call assert_false(exists('*{' . funcnumber . '}'))
+endfunc
diff --git a/src/version.c b/src/version.c
index c9f1926acf..1a02fbe921 100644
--- a/src/version.c
+++ b/src/version.c
@@ -749,6 +749,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1638,
+/**/
1637,
/**/
1636,