comparison src/list.c @ 27517:f00a7a2bee21 v8.2.4286

patch 8.2.4286: Vim9: strict type checking after copy() and deepcopy() Commit: https://github.com/vim/vim/commit/381692b6f1c2ec9b73a139500286ddc9347a1c01 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 2 20:01:27 2022 +0000 patch 8.2.4286: Vim9: strict type checking after copy() and deepcopy() Problem: Vim9: strict type checking after copy() and deepcopy(). Solution: Allow type to change after making a copy. (closes https://github.com/vim/vim/issues/9644)
author Bram Moolenaar <Bram@vim.org>
date Wed, 02 Feb 2022 21:15:03 +0100
parents c7f614c9ceb3
children 4ca0ee7b4f86
comparison
equal deleted inserted replaced
27516:fdcbdd530e4c 27517:f00a7a2bee21
1013 if (l == NULL) 1013 if (l == NULL)
1014 return; 1014 return;
1015 1015
1016 if (make_copy) 1016 if (make_copy)
1017 { 1017 {
1018 l = list_copy(l, TRUE, get_copyID()); 1018 l = list_copy(l, TRUE, TRUE, get_copyID());
1019 rettv->vval.v_list = l; 1019 rettv->vval.v_list = l;
1020 if (l == NULL) 1020 if (l == NULL)
1021 return; 1021 return;
1022 // The type will change. 1022 // The type will change.
1023 free_type(l->lv_type); 1023 free_type(l->lv_type);
1100 1100
1101 // make a copy of the first list. 1101 // make a copy of the first list.
1102 if (l1 == NULL) 1102 if (l1 == NULL)
1103 l = list_alloc(); 1103 l = list_alloc();
1104 else 1104 else
1105 l = list_copy(l1, FALSE, 0); 1105 l = list_copy(l1, FALSE, TRUE, 0);
1106 if (l == NULL) 1106 if (l == NULL)
1107 return FAIL; 1107 return FAIL;
1108 tv->v_type = VAR_LIST; 1108 tv->v_type = VAR_LIST;
1109 tv->v_lock = 0; 1109 tv->v_lock = 0;
1110 tv->vval.v_list = l; 1110 tv->vval.v_list = l;
1198 } 1198 }
1199 1199
1200 /* 1200 /*
1201 * Make a copy of list "orig". Shallow if "deep" is FALSE. 1201 * Make a copy of list "orig". Shallow if "deep" is FALSE.
1202 * The refcount of the new list is set to 1. 1202 * The refcount of the new list is set to 1.
1203 * See item_copy() for "copyID". 1203 * See item_copy() for "top" and "copyID".
1204 * Returns NULL when out of memory. 1204 * Returns NULL when out of memory.
1205 */ 1205 */
1206 list_T * 1206 list_T *
1207 list_copy(list_T *orig, int deep, int copyID) 1207 list_copy(list_T *orig, int deep, int top, int copyID)
1208 { 1208 {
1209 list_T *copy; 1209 list_T *copy;
1210 listitem_T *item; 1210 listitem_T *item;
1211 listitem_T *ni; 1211 listitem_T *ni;
1212 1212
1214 return NULL; 1214 return NULL;
1215 1215
1216 copy = list_alloc(); 1216 copy = list_alloc();
1217 if (copy != NULL) 1217 if (copy != NULL)
1218 { 1218 {
1219 copy->lv_type = alloc_type(orig->lv_type); 1219 copy->lv_type = alloc_type(top || deep ? &t_list_any: orig->lv_type);
1220 if (copyID != 0) 1220 if (copyID != 0)
1221 { 1221 {
1222 // Do this before adding the items, because one of the items may 1222 // Do this before adding the items, because one of the items may
1223 // refer back to this list. 1223 // refer back to this list.
1224 orig->lv_copyID = copyID; 1224 orig->lv_copyID = copyID;
1231 ni = listitem_alloc(); 1231 ni = listitem_alloc();
1232 if (ni == NULL) 1232 if (ni == NULL)
1233 break; 1233 break;
1234 if (deep) 1234 if (deep)
1235 { 1235 {
1236 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 1236 if (item_copy(&item->li_tv, &ni->li_tv,
1237 deep, FALSE, copyID) == FAIL)
1237 { 1238 {
1238 vim_free(ni); 1239 vim_free(ni);
1239 break; 1240 break;
1240 } 1241 }
1241 } 1242 }
2699 emsg(_(e_cannot_extend_null_list)); 2700 emsg(_(e_cannot_extend_null_list));
2700 return; 2701 return;
2701 } 2702 }
2702 l2 = argvars[1].vval.v_list; 2703 l2 = argvars[1].vval.v_list;
2703 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE)) 2704 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
2704 && l2 != NULL) 2705 && l2 != NULL)
2705 { 2706 {
2706 if (is_new) 2707 if (is_new)
2707 { 2708 {
2708 l1 = list_copy(l1, FALSE, get_copyID()); 2709 l1 = list_copy(l1, FALSE, TRUE, get_copyID());
2709 if (l1 == NULL) 2710 if (l1 == NULL)
2710 return; 2711 return;
2711 } 2712 }
2712 2713
2713 if (argvars[2].v_type != VAR_UNKNOWN) 2714 if (argvars[2].v_type != VAR_UNKNOWN)