Patch 8.2.4529

6 views
Skip to first unread message

Bram Moolenaar

unread,
Mar 8, 2022, 2:44:53 PM3/8/22
to vim...@googlegroups.com

Patch 8.2.4529
Problem: Vim9: comparing partial with function fails.
Solution: Support this comparison. Avoid a crash. (closes #9909)
Add more test cases.
Files: src/vim9instr.c, src/userfunc.c, src/vim9type.c,
src/testdir/test_vim9_builtin.vim, src/testdir/test_vim9_expr.vim,
src/testdir/test_vim9_func.vim, src/testdir/test_vimscript.vim


*** ../vim-8.2.4528/src/vim9instr.c 2022-03-08 13:18:10.809020782 +0000
--- src/vim9instr.c 2022-03-08 18:58:21.949496564 +0000
***************
*** 370,376 ****
}
else if (type1 == VAR_ANY || type2 == VAR_ANY
|| ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
! && (type2 == VAR_NUMBER || type2 == VAR_FLOAT)))
isntype = ISN_COMPAREANY;
else if (type1 == VAR_SPECIAL || type2 == VAR_SPECIAL)
{
--- 370,378 ----
}
else if (type1 == VAR_ANY || type2 == VAR_ANY
|| ((type1 == VAR_NUMBER || type1 == VAR_FLOAT)
! && (type2 == VAR_NUMBER || type2 == VAR_FLOAT))
! || (type1 == VAR_FUNC && type2 == VAR_PARTIAL)
! || (type1 == VAR_PARTIAL && type2 == VAR_FUNC))
isntype = ISN_COMPAREANY;
else if (type1 == VAR_SPECIAL || type2 == VAR_SPECIAL)
{
*** ../vim-8.2.4528/src/userfunc.c 2022-03-08 16:52:18.807756958 +0000
--- src/userfunc.c 2022-03-08 19:16:32.579191126 +0000
***************
*** 5730,5747 ****
make_partial(dict_T *selfdict_in, typval_T *rettv)
{
char_u *fname;
! ufunc_T *fp;
char_u fname_buf[FLEN_FIXED + 1];
int error;
dict_T *selfdict = selfdict_in;

! if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial->pt_func != NULL)
fp = rettv->vval.v_partial->pt_func;
else
{
fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
: rettv->vval.v_partial->pt_name;
! if (fname != NULL)
{
char_u *tofree = NULL;

--- 5730,5756 ----
make_partial(dict_T *selfdict_in, typval_T *rettv)
{
char_u *fname;
! ufunc_T *fp = NULL;
char_u fname_buf[FLEN_FIXED + 1];
int error;
dict_T *selfdict = selfdict_in;

! if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial != NULL
! && rettv->vval.v_partial->pt_func != NULL)
fp = rettv->vval.v_partial->pt_func;
else
{
fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
+ : rettv->vval.v_partial == NULL ? NULL
: rettv->vval.v_partial->pt_name;
! if (fname == NULL)
! {
! // There is no point binding a dict to a NULL function, just create
! // a function reference.
! rettv->v_type = VAR_FUNC;
! rettv->vval.v_string = NULL;
! }
! else
{
char_u *tofree = NULL;

***************
*** 5752,5759 ****
}
}

! if ((fp != NULL && (fp->uf_flags & FC_DICT))
! || (rettv->v_type == VAR_FUNC && rettv->vval.v_string == NULL))
{
partial_T *pt = ALLOC_CLEAR_ONE(partial_T);

--- 5761,5767 ----
}
}

! if (fp != NULL && (fp->uf_flags & FC_DICT))
{
partial_T *pt = ALLOC_CLEAR_ONE(partial_T);

*** ../vim-8.2.4528/src/vim9type.c 2022-03-08 13:18:10.809020782 +0000
--- src/vim9type.c 2022-03-08 19:38:42.740545016 +0000
***************
*** 420,425 ****
--- 420,427 ----
}
else
name = tv->vval.v_string;
+ if (name == NULL && ufunc == NULL)
+ return &t_func_unknown;
if (name != NULL)
{
int idx = find_internal_func(name);
*** ../vim-8.2.4528/src/testdir/test_vim9_builtin.vim 2022-02-23 21:03:28.913442583 +0000
--- src/testdir/test_vim9_builtin.vim 2022-03-08 19:40:04.756387254 +0000
***************
*** 1687,1692 ****
--- 1687,1693 ----
endif
$SOMEENVVAR = 'some'
assert_equal('some', getenv('SOMEENVVAR'))
+ assert_notequal(null, getenv('SOMEENVVAR'))
unlet $SOMEENVVAR
getenv('')->assert_equal(v:null)
enddef
***************
*** 4398,4404 ****
if has('float')
assert_equal('func([unknown], [unknown]): float', typename(function('pow')))
endif
! assert_equal('func', test_null_partial()->typename())
assert_equal('list<unknown>', test_null_list()->typename())
assert_equal('dict<unknown>', test_null_dict()->typename())
if has('job')
--- 4399,4405 ----
if has('float')
assert_equal('func([unknown], [unknown]): float', typename(function('pow')))
endif
! assert_equal('func(...): unknown', test_null_partial()->typename())
assert_equal('list<unknown>', test_null_list()->typename())
assert_equal('dict<unknown>', test_null_dict()->typename())
if has('job')
*** ../vim-8.2.4528/src/testdir/test_vim9_expr.vim 2022-03-01 19:23:20.544357315 +0000
--- src/testdir/test_vim9_expr.vim 2022-03-08 19:19:38.126801608 +0000
***************
*** 717,737 ****
--- 717,749 ----
g:not_null_list = []
var lines =<< trim END
assert_true(test_null_blob() == v:null)
+ assert_true(null_blob == null)
assert_true(v:null == test_null_blob())
+ assert_true(null == null_blob)
assert_false(test_null_blob() != v:null)
+ assert_false(null_blob != null)
assert_false(v:null != test_null_blob())
+ assert_false(null != null_blob)

if has('channel')
assert_true(test_null_channel() == v:null)
+ assert_true(null_channel == null)
assert_true(v:null == test_null_channel())
+ assert_true(null == null_channel)
assert_false(test_null_channel() != v:null)
+ assert_false(null_channel != null)
assert_false(v:null != test_null_channel())
+ assert_false(null != null_channel)
endif

assert_true(test_null_dict() == v:null)
+ assert_true(null_dict == null)
assert_true(v:null == test_null_dict())
+ assert_true(null == null_dict)
assert_false(test_null_dict() != v:null)
+ assert_false(null_dict != null)
assert_false(v:null != test_null_dict())
+ assert_false(null != null_dict)

assert_true(g:null_dict == v:null)
assert_true(v:null == g:null_dict)
***************
*** 739,759 ****
--- 751,783 ----
assert_false(v:null != g:null_dict)

assert_true(test_null_function() == v:null)
+ assert_true(null_function == null)
assert_true(v:null == test_null_function())
+ assert_true(null == null_function)
assert_false(test_null_function() != v:null)
+ assert_false(null_function != null)
assert_false(v:null != test_null_function())
+ assert_false(null != null_function)

if has('job')
assert_true(test_null_job() == v:null)
+ assert_true(null_job == null)
assert_true(v:null == test_null_job())
+ assert_true(null == null_job)
assert_false(test_null_job() != v:null)
+ assert_false(null_job != null)
assert_false(v:null != test_null_job())
+ assert_false(null != null_job)
endif

assert_true(test_null_list() == v:null)
+ assert_true(null_list == null)
assert_true(v:null == test_null_list())
+ assert_true(null == null_list)
assert_false(test_null_list() != v:null)
+ assert_false(null_list != null)
assert_false(v:null != test_null_list())
+ assert_false(null != null_list)

assert_false(g:not_null_list == v:null)
assert_false(v:null == g:not_null_list)
***************
*** 761,779 ****
--- 785,817 ----
assert_true(v:null != g:not_null_list)

assert_true(test_null_partial() == v:null)
+ assert_true(null_partial == null)
assert_true(v:null == test_null_partial())
+ assert_true(null == null_partial)
assert_false(test_null_partial() != v:null)
+ assert_false(null_partial != null)
assert_false(v:null != test_null_partial())
+ assert_false(null != null_partial)

assert_true(test_null_string() == v:null)
+ assert_true(null_string == null)
assert_true(v:null == test_null_string())
+ assert_true(null == null_string)
assert_false(test_null_string() != v:null)
+ assert_false(null_string != null)
assert_false(v:null != test_null_string())
+ assert_false(null != null_string)
END
v9.CheckDefAndScriptSuccess(lines)
unlet g:null_dict
unlet g:not_null_list

+ lines =<< trim END
+ var d: dict<func> = {f: null_function}
+ assert_equal(null_function, d.f)
+ END
+ v9.CheckDefAndScriptSuccess(lines)
+
v9.CheckDefAndScriptFailure(['echo 123 == v:null'], 'E1072: Cannot compare number with special')
v9.CheckDefAndScriptFailure(['echo v:null == 123'], 'E1072: Cannot compare special with number')
v9.CheckDefAndScriptFailure(['echo 123 != v:null'], 'E1072: Cannot compare number with special')
*** ../vim-8.2.4528/src/testdir/test_vim9_func.vim 2022-03-08 16:52:18.807756958 +0000
--- src/testdir/test_vim9_func.vim 2022-03-08 19:27:47.821817178 +0000
***************
*** 3341,3347 ****
var lines =<< trim END
var d: dict<func> = {f: null_function}
var Ref = d.f
! assert_equal('func', typename(Ref))
END
v9.CheckDefAndScriptSuccess(lines)
enddef
--- 3341,3347 ----
var lines =<< trim END
var d: dict<func> = {f: null_function}
var Ref = d.f
! assert_equal('func(...): unknown', typename(Ref))
END
v9.CheckDefAndScriptSuccess(lines)
enddef
*** ../vim-8.2.4528/src/testdir/test_vimscript.vim 2022-03-02 13:13:26.475857972 +0000
--- src/testdir/test_vimscript.vim 2022-03-02 14:46:33.321695479 +0000
***************
*** 6571,6576 ****
--- 6571,6579 ----
call assert_false(v:true is 1)
call assert_false(v:true is v:false)
call assert_false(v:none is 0)
+ call assert_false(v:none is [])
+ call assert_false(v:none is {})
+ call assert_false(v:none is 'text')
call assert_false(v:null is 0)
call assert_false(v:null is v:none)

*** ../vim-8.2.4528/src/version.c 2022-03-08 16:52:18.807756958 +0000
--- src/version.c 2022-03-08 19:00:28.957245068 +0000
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 4529,
/**/

--
hundred-and-one symptoms of being an internet addict:
207. You're given one phone call in prison and you ask them for a laptop.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages