diff src/vim9compile.c @ 23458:d2b1269c2c68 v8.2.2272

patch 8.2.2272: Vim9: extend() can violate the type of a variable Commit: https://github.com/vim/vim/commit/aa210a3aeccc33c6051978017959126b037f94af Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 2 15:41:03 2021 +0100 patch 8.2.2272: Vim9: extend() can violate the type of a variable Problem: Vim9: extend() can violate the type of a variable. Solution: Add the type to the dictionary or list and check items against it. (closes #7593)
author Bram Moolenaar <Bram@vim.org>
date Sat, 02 Jan 2021 15:45:04 +0100
parents a8e7acf71fa4
children ad83c0ff34c0
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -831,6 +831,20 @@ generate_TYPECHECK(
     return OK;
 }
 
+    static int
+generate_SETTYPE(
+	cctx_T	    *cctx,
+	type_T	    *expected)
+{
+    isn_T	*isn;
+
+    RETURN_OK_IF_SKIP(cctx);
+    if ((isn = generate_instr(cctx, ISN_SETTYPE)) == NULL)
+	return FAIL;
+    isn->isn_arg.type.ct_type = alloc_type(expected);
+    return OK;
+}
+
 /*
  * Return TRUE if "actual" could be "expected" and a runtime typecheck is to be
  * used.  Return FALSE if the types will never match.
@@ -6025,6 +6039,15 @@ compile_assignment(char_u *arg, exarg_T 
 		// ":const var": lock the value, but not referenced variables
 		generate_LOCKCONST(cctx);
 
+	    if (is_decl
+		    && (type->tt_type == VAR_DICT || type->tt_type == VAR_LIST)
+		    && type->tt_member != NULL
+		    && type->tt_member != &t_any
+		    && type->tt_member != &t_unknown)
+		// Set the type in the list or dict, so that it can be checked,
+		// also in legacy script.
+		generate_SETTYPE(cctx, type);
+
 	    if (dest != dest_local)
 	    {
 		if (generate_store_var(cctx, dest, opt_flags, vimvaridx,
@@ -8193,6 +8216,7 @@ delete_instr(isn_T *isn)
 	    break;
 
 	case ISN_CHECKTYPE:
+	case ISN_SETTYPE:
 	    free_type(isn->isn_arg.type.ct_type);
 	    break;