Mercurial > vim
diff 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 |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1240,13 +1240,16 @@ generate_PUSHFUNC(cctx_T *cctx, char_u * /* * Generate an ISN_GETITEM instruction with "index". - */ - static int -generate_GETITEM(cctx_T *cctx, int index) + * "with_op" is TRUE for "+=" and other operators, the stack has the current + * value below the list with values. + */ + static int +generate_GETITEM(cctx_T *cctx, int index, int with_op) { isn_T *isn; garray_T *stack = &cctx->ctx_type_stack; - type_T *type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + type_T *type = ((type_T **)stack->ga_data)[stack->ga_len + - (with_op ? 2 : 1)]; type_T *item_type = &t_any; RETURN_OK_IF_SKIP(cctx); @@ -1260,7 +1263,8 @@ generate_GETITEM(cctx_T *cctx, int index item_type = type->tt_member; if ((isn = generate_instr(cctx, ISN_GETITEM)) == NULL) return FAIL; - isn->isn_arg.number = index; + isn->isn_arg.getitem.gi_index = index; + isn->isn_arg.getitem.gi_with_op = with_op; // add the item type to the type stack if (ga_grow(stack, 1) == FAIL) @@ -6746,19 +6750,17 @@ compile_assignment(char_u *arg, exarg_T int is_const = FALSE; char_u *wp; + // for "+=", "*=", "..=" etc. first load the current value + if (*op != '=' + && compile_load_lhs_with_index(&lhs, var_start, + cctx) == FAIL) + goto theend; + // For "var = expr" evaluate the expression. if (var_count == 0) { int r; - // for "+=", "*=", "..=" etc. first load the current value - if (*op != '=') - { - if (compile_load_lhs_with_index(&lhs, var_start, - cctx) == FAIL) - goto theend; - } - // Compile the expression. instr_count = instr->ga_len; if (incdec) @@ -6795,7 +6797,7 @@ compile_assignment(char_u *arg, exarg_T { // For "[var, var] = expr" get the "var_idx" item from the // list. - if (generate_GETITEM(cctx, var_idx) == FAIL) + if (generate_GETITEM(cctx, var_idx, *op != '=') == FAIL) goto theend; }