comparison src/vim9compile.c @ 24984:71b1e2ef0069 v8.2.3029

patch 8.2.3029: Vim9: crash when using operator and list unpack assignment Commit: https://github.com/vim/vim/commit/035bd1c99f2a8eda5ee886adde4f97ea71fb167f Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jun 21 19:44:11 2021 +0200 patch 8.2.3029: Vim9: crash when using operator and list unpack assignment Problem: Vim9: crash when using operator and list unpack assignment. (Naohiro Ono) Solution: Get variable value before operation. (closes #8416)
author Bram Moolenaar <Bram@vim.org>
date Mon, 21 Jun 2021 19:45:03 +0200
parents d0b6a8d82cef
children 70f55a30f03c
comparison
equal deleted inserted replaced
24983:94f7f4cd68b7 24984:71b1e2ef0069
1238 return OK; 1238 return OK;
1239 } 1239 }
1240 1240
1241 /* 1241 /*
1242 * Generate an ISN_GETITEM instruction with "index". 1242 * Generate an ISN_GETITEM instruction with "index".
1243 */ 1243 * "with_op" is TRUE for "+=" and other operators, the stack has the current
1244 static int 1244 * value below the list with values.
1245 generate_GETITEM(cctx_T *cctx, int index) 1245 */
1246 static int
1247 generate_GETITEM(cctx_T *cctx, int index, int with_op)
1246 { 1248 {
1247 isn_T *isn; 1249 isn_T *isn;
1248 garray_T *stack = &cctx->ctx_type_stack; 1250 garray_T *stack = &cctx->ctx_type_stack;
1249 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; 1251 type_T *type = ((type_T **)stack->ga_data)[stack->ga_len
1252 - (with_op ? 2 : 1)];
1250 type_T *item_type = &t_any; 1253 type_T *item_type = &t_any;
1251 1254
1252 RETURN_OK_IF_SKIP(cctx); 1255 RETURN_OK_IF_SKIP(cctx);
1253 1256
1254 if (type->tt_type != VAR_LIST) 1257 if (type->tt_type != VAR_LIST)
1258 return FAIL; 1261 return FAIL;
1259 } 1262 }
1260 item_type = type->tt_member; 1263 item_type = type->tt_member;
1261 if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL) 1264 if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL)
1262 return FAIL; 1265 return FAIL;
1263 isn->isn_arg.number = index; 1266 isn->isn_arg.getitem.gi_index = index;
1267 isn->isn_arg.getitem.gi_with_op = with_op;
1264 1268
1265 // add the item type to the type stack 1269 // add the item type to the type stack
1266 if (ga_grow(stack, 1) == FAIL) 1270 if (ga_grow(stack, 1) == FAIL)
1267 return FAIL; 1271 return FAIL;
1268 ((type_T **)stack->ga_data)[stack->ga_len] = item_type; 1272 ((type_T **)stack->ga_data)[stack->ga_len] = item_type;
6744 else if (oplen > 0) 6748 else if (oplen > 0)
6745 { 6749 {
6746 int is_const = FALSE; 6750 int is_const = FALSE;
6747 char_u *wp; 6751 char_u *wp;
6748 6752
6753 // for "+=", "*=", "..=" etc. first load the current value
6754 if (*op != '='
6755 && compile_load_lhs_with_index(&lhs, var_start,
6756 cctx) == FAIL)
6757 goto theend;
6758
6749 // For "var = expr" evaluate the expression. 6759 // For "var = expr" evaluate the expression.
6750 if (var_count == 0) 6760 if (var_count == 0)
6751 { 6761 {
6752 int r; 6762 int r;
6753
6754 // for "+=", "*=", "..=" etc. first load the current value
6755 if (*op != '=')
6756 {
6757 if (compile_load_lhs_with_index(&lhs, var_start,
6758 cctx) == FAIL)
6759 goto theend;
6760 }
6761 6763
6762 // Compile the expression. 6764 // Compile the expression.
6763 instr_count = instr->ga_len; 6765 instr_count = instr->ga_len;
6764 if (incdec) 6766 if (incdec)
6765 { 6767 {
6793 } 6795 }
6794 else 6796 else
6795 { 6797 {
6796 // For "[var, var] = expr" get the "var_idx" item from the 6798 // For "[var, var] = expr" get the "var_idx" item from the
6797 // list. 6799 // list.
6798 if (generate_GETITEM(cctx, var_idx) == FAIL) 6800 if (generate_GETITEM(cctx, var_idx, *op != '=') == FAIL)
6799 goto theend; 6801 goto theend;
6800 } 6802 }
6801 6803
6802 rhs_type = stack->ga_len == 0 ? &t_void 6804 rhs_type = stack->ga_len == 0 ? &t_void
6803 : ((type_T **)stack->ga_data)[stack->ga_len - 1]; 6805 : ((type_T **)stack->ga_data)[stack->ga_len - 1];