forked from aniani/vim
patch 8.2.1176: Vim9: not enough type checking in Vim9 script
Problem: Vim9: not enough type checking in Vim9 script. Solution: Use same type checking as in a :def function.
This commit is contained in:
10
src/eval.c
10
src/eval.c
@@ -2460,8 +2460,16 @@ eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
}
|
||||
if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE))
|
||||
{
|
||||
int ret = typval_compare(rettv, &var2, type, ic);
|
||||
int ret;
|
||||
|
||||
if (in_vim9script() && check_compare_types(
|
||||
type, rettv, &var2) == FAIL)
|
||||
{
|
||||
ret = FAIL;
|
||||
clear_tv(rettv);
|
||||
}
|
||||
else
|
||||
ret = typval_compare(rettv, &var2, type, ic);
|
||||
clear_tv(&var2);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ int check_defined(char_u *p, size_t len, cctx_T *cctx);
|
||||
void clear_type_list(garray_T *gap);
|
||||
type_T *typval2type(typval_T *tv);
|
||||
int check_type(type_T *expected, type_T *actual, int give_msg);
|
||||
int check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2);
|
||||
char_u *skip_type(char_u *start);
|
||||
type_T *parse_type(char_u **arg, garray_T *type_gap);
|
||||
char *vartype_name(vartype_T type);
|
||||
|
@@ -557,7 +557,7 @@ def RetVoid()
|
||||
enddef
|
||||
|
||||
def Test_expr4_vimscript()
|
||||
" only checks line continuation
|
||||
" check line continuation
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
let var = 0
|
||||
@@ -599,6 +599,25 @@ def Test_expr4_vimscript()
|
||||
assert_equal(1, var)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
" spot check mismatching types
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
echo '' == 0
|
||||
END
|
||||
CheckScriptFailure(lines, 'E1072:')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
echo v:true > v:false
|
||||
END
|
||||
CheckScriptFailure(lines, 'Cannot compare bool with bool')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
echo 123 is 123
|
||||
END
|
||||
CheckScriptFailure(lines, 'Cannot use "is" with number')
|
||||
enddef
|
||||
|
||||
func Test_expr4_fails()
|
||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1176,
|
||||
/**/
|
||||
1175,
|
||||
/**/
|
||||
|
@@ -820,6 +820,14 @@ get_compare_isn(exptype_T exptype, vartype_T type1, vartype_T type2)
|
||||
return isntype;
|
||||
}
|
||||
|
||||
int
|
||||
check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2)
|
||||
{
|
||||
if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
|
||||
return FAIL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an ISN_COMPARE* instruction with a boolean result.
|
||||
*/
|
||||
@@ -4296,7 +4304,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
// Both sides are a constant, compute the result now.
|
||||
// First check for a valid combination of types, this is more
|
||||
// strict than typval_compare().
|
||||
if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
|
||||
if (check_compare_types(type, tv1, tv2) == FAIL)
|
||||
ret = FAIL;
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user