0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.1.0952: Vim9: missing type checking for any type assignment

Problem:  Vim9: missing type checking for any type assignment
          (Ernie Rael)
Solution: when assigning to a list item, if the type of the LHS item is
          any, then use the list item type (Yegappan Lakshmanan)

fixes: #15208
closes: #16274

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2024-12-22 14:44:35 +01:00
committed by Christian Brabandt
parent 62e3014ab1
commit 92195ae72f
5 changed files with 85 additions and 2 deletions

View File

@@ -2215,6 +2215,25 @@ handle_debug(isn_T *iptr, ectx_T *ectx)
vim_free(line);
}
/*
* Do a runtime check of the RHS value against the LHS List member type.
* This is used by the STOREINDEX instruction to perform a type check
* at runtime if compile time type check cannot be performed (VAR_ANY).
* Returns FAIL if there is a type mismatch.
*/
static int
storeindex_check_list_member_type(
list_T *lhs_list,
typval_T *rhs_tv,
ectx_T *ectx)
{
if (lhs_list->lv_type == NULL || lhs_list->lv_type->tt_member == NULL)
return OK;
return check_typval_type(lhs_list->lv_type->tt_member, rhs_tv,
ectx->ec_where);
}
/*
* Store a value in a list, dict, blob or object variable.
* Returns OK, FAIL or NOTDONE (uncatchable error).
@@ -2228,6 +2247,7 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
long lidx = 0;
typval_T *tv_dest = STACK_TV_BOT(-1);
int status = OK;
int check_rhs_type = FALSE;
if (tv_idx->v_type == VAR_NUMBER)
lidx = (long)tv_idx->vval.v_number;
@@ -2247,6 +2267,7 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
}
else if (dest_type == VAR_ANY)
{
check_rhs_type = TRUE;
dest_type = tv_dest->v_type;
if (dest_type == VAR_DICT)
status = do_2string(tv_idx, TRUE, FALSE);
@@ -2327,6 +2348,12 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
semsg(_(e_list_index_out_of_range_nr), lidx);
return FAIL;
}
// Do a runtime type check for VAR_ANY
if (check_rhs_type &&
storeindex_check_list_member_type(list, tv, ectx) == FAIL)
return FAIL;
if (lidx < list->lv_len)
{
listitem_T *li = list_find(list, lidx);
@@ -6304,7 +6331,7 @@ call_def_function(
else if (check_typval_arg_type(expected, tv,
NULL, argv_idx + 1) == FAIL)
goto failed_early;
}
}
if (!done)
copy_tv(tv, STACK_TV_BOT(0));
}