Mercurial > vim
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;