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))
|
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);
|
clear_tv(&var2);
|
||||||
return ret;
|
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);
|
void clear_type_list(garray_T *gap);
|
||||||
type_T *typval2type(typval_T *tv);
|
type_T *typval2type(typval_T *tv);
|
||||||
int check_type(type_T *expected, type_T *actual, int give_msg);
|
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);
|
char_u *skip_type(char_u *start);
|
||||||
type_T *parse_type(char_u **arg, garray_T *type_gap);
|
type_T *parse_type(char_u **arg, garray_T *type_gap);
|
||||||
char *vartype_name(vartype_T type);
|
char *vartype_name(vartype_T type);
|
||||||
|
@@ -557,7 +557,7 @@ def RetVoid()
|
|||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_expr4_vimscript()
|
def Test_expr4_vimscript()
|
||||||
" only checks line continuation
|
" check line continuation
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
let var = 0
|
let var = 0
|
||||||
@@ -599,6 +599,25 @@ def Test_expr4_vimscript()
|
|||||||
assert_equal(1, var)
|
assert_equal(1, var)
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
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
|
enddef
|
||||||
|
|
||||||
func Test_expr4_fails()
|
func Test_expr4_fails()
|
||||||
|
@@ -754,6 +754,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1176,
|
||||||
/**/
|
/**/
|
||||||
1175,
|
1175,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -820,6 +820,14 @@ get_compare_isn(exptype_T exptype, vartype_T type1, vartype_T type2)
|
|||||||
return isntype;
|
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.
|
* 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.
|
// Both sides are a constant, compute the result now.
|
||||||
// First check for a valid combination of types, this is more
|
// First check for a valid combination of types, this is more
|
||||||
// strict than typval_compare().
|
// 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;
|
ret = FAIL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user