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