comparison src/vim9compile.c @ 21576:f4252efe370e v8.2.1338

patch 8.2.1338: Vim9: assigning to script-local variable doesn't check type Commit: https://github.com/vim/vim/commit/8e4c8c853e3ffbd9258f89180692879ec6bce72b Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 1 15:38:38 2020 +0200 patch 8.2.1338: Vim9: assigning to script-local variable doesn't check type Problem: Vim9: assigning to script-local variable doesn't check type. Solution: Use the type. (issue https://github.com/vim/vim/issues/6591)
author Bram Moolenaar <Bram@vim.org>
date Sat, 01 Aug 2020 15:45:06 +0200
parents 30a997217524
children 7417cb54cb24
comparison
equal deleted inserted replaced
21575:69d8fbc507a1 21576:f4252efe370e
5068 char_u *p; 5068 char_u *p;
5069 char_u *end = arg; 5069 char_u *end = arg;
5070 char_u *ret = NULL; 5070 char_u *ret = NULL;
5071 int var_count = 0; 5071 int var_count = 0;
5072 int var_idx; 5072 int var_idx;
5073 int scriptvar_sid = 0;
5074 int scriptvar_idx = -1;
5073 int semicolon = 0; 5075 int semicolon = 0;
5074 garray_T *instr = &cctx->ctx_instr; 5076 garray_T *instr = &cctx->ctx_instr;
5075 garray_T *stack = &cctx->ctx_type_stack; 5077 garray_T *stack = &cctx->ctx_type_stack;
5076 char_u *op; 5078 char_u *op;
5077 int oplen = 0; 5079 int oplen = 0;
5331 goto theend; 5333 goto theend;
5332 } 5334 }
5333 } 5335 }
5334 else 5336 else
5335 { 5337 {
5336 int idx; 5338 int idx;
5339 imported_T *import = NULL;
5337 5340
5338 for (idx = 0; reserved[idx] != NULL; ++idx) 5341 for (idx = 0; reserved[idx] != NULL; ++idx)
5339 if (STRCMP(reserved[idx], name) == 0) 5342 if (STRCMP(reserved[idx], name) == 0)
5340 { 5343 {
5341 semsg(_("E1034: Cannot use reserved name %s"), name); 5344 semsg(_("E1034: Cannot use reserved name %s"), name);
5372 goto theend; 5375 goto theend;
5373 } 5376 }
5374 } 5377 }
5375 else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0) 5378 else if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)
5376 || lookup_script(var_start, varlen) == OK 5379 || lookup_script(var_start, varlen) == OK
5377 || find_imported(var_start, varlen, cctx) != NULL) 5380 || (import = find_imported(var_start, varlen, cctx))
5381 != NULL)
5378 { 5382 {
5379 dest = dest_script; 5383 char_u *rawname = name + (name[1] == ':' ? 2 : 0);
5384
5380 if (is_decl) 5385 if (is_decl)
5381 { 5386 {
5382 if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0)) 5387 if ((varlen > 1 && STRNCMP(var_start, "s:", 2) == 0))
5383 semsg(_("E1101: Cannot declare a script variable in a function: %s"), 5388 semsg(_("E1101: Cannot declare a script variable in a function: %s"),
5384 name); 5389 name);
5385 else 5390 else
5386 semsg(_("E1054: Variable already declared in the script: %s"), 5391 semsg(_("E1054: Variable already declared in the script: %s"),
5387 name); 5392 name);
5388 goto theend; 5393 goto theend;
5394 }
5395 dest = dest_script;
5396
5397 // existing script-local variables should have a type
5398 scriptvar_sid = current_sctx.sc_sid;
5399 if (import != NULL)
5400 scriptvar_sid = import->imp_sid;
5401 scriptvar_idx = get_script_item_idx(scriptvar_sid,
5402 rawname, TRUE);
5403 if (scriptvar_idx >= 0)
5404 {
5405 scriptitem_T *si = SCRIPT_ITEM(scriptvar_sid);
5406 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
5407 + scriptvar_idx;
5408 type = sv->sv_type;
5389 } 5409 }
5390 } 5410 }
5391 else if (name[1] == ':' && name[2] != NUL) 5411 else if (name[1] == ':' && name[2] != NUL)
5392 { 5412 {
5393 semsg(_("E1082: Cannot use a namespaced variable: %s"), 5413 semsg(_("E1082: Cannot use a namespaced variable: %s"),
5764 case dest_vimvar: 5784 case dest_vimvar:
5765 generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL); 5785 generate_STORE(cctx, ISN_STOREV, vimvaridx, NULL);
5766 break; 5786 break;
5767 case dest_script: 5787 case dest_script:
5768 { 5788 {
5769 char_u *rawname = name + (name[1] == ':' ? 2 : 0); 5789 if (scriptvar_idx < 0)
5770 imported_T *import = NULL;
5771 int sid = current_sctx.sc_sid;
5772 int idx;
5773
5774 if (name[1] != ':')
5775 {
5776 import = find_imported(name, 0, cctx);
5777 if (import != NULL)
5778 sid = import->imp_sid;
5779 }
5780
5781 idx = get_script_item_idx(sid, rawname, TRUE);
5782 // TODO: specific type
5783 if (idx < 0)
5784 { 5790 {
5785 char_u *name_s = name; 5791 char_u *name_s = name;
5786 5792
5787 // Include s: in the name for store_var() 5793 // Include s: in the name for store_var()
5788 if (name[1] != ':') 5794 if (name[1] != ':')
5794 name_s = name; 5800 name_s = name;
5795 else 5801 else
5796 vim_snprintf((char *)name_s, len, 5802 vim_snprintf((char *)name_s, len,
5797 "s:%s", name); 5803 "s:%s", name);
5798 } 5804 }
5799 generate_OLDSCRIPT(cctx, ISN_STORES, name_s, sid, 5805 generate_OLDSCRIPT(cctx, ISN_STORES, name_s,
5800 &t_any); 5806 scriptvar_sid, type);
5801 if (name_s != name) 5807 if (name_s != name)
5802 vim_free(name_s); 5808 vim_free(name_s);
5803 } 5809 }
5804 else 5810 else
5805 generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT, 5811 generate_VIM9SCRIPT(cctx, ISN_STORESCRIPT,
5806 sid, idx, &t_any); 5812 scriptvar_sid, scriptvar_idx, type);
5807 } 5813 }
5808 break; 5814 break;
5809 case dest_local: 5815 case dest_local:
5810 if (lvar != NULL) 5816 if (lvar != NULL)
5811 { 5817 {