Patch 9.0.1052
Problem: Using freed memory on exit when EXITFREE is defined.
Solution: Make a deep copy of the type. Make sure TTFLAG_STATIC is not set
in the copy.
Files: src/vim9type.c
*** ../vim-9.0.1051/src/vim9type.c 2022-12-12 18:56:27.877463284 +0000
--- src/vim9type.c 2022-12-13 13:40:59.223860093 +0000
***************
*** 57,62 ****
--- 57,63 ----
if (copy == NULL)
return type;
*copy = *type;
+ copy->tt_flags &= ~TTFLAG_STATIC;
if (type->tt_args != NULL
&& func_type_add_arg_types(copy, type->tt_argcount, type_gap) == OK)
***************
*** 66,71 ****
--- 67,120 ----
return copy;
}
+ /*
+ * Inner part of copy_type_deep().
+ * When allocation fails returns "type".
+ */
+ static type_T *
+ copy_type_deep_rec(type_T *type, garray_T *type_gap, garray_T *seen_types)
+ {
+ for (int i = 0; i < seen_types->ga_len; ++i)
+ if (((type_T **)seen_types->ga_data)[i * 2] == type)
+ // seen this type before, return the copy we made
+ return ((type_T **)seen_types->ga_data)[i * 2 + 1];
+
+ type_T *copy = copy_type(type, type_gap);
+ if (ga_grow(seen_types, 1) == FAIL)
+ return copy;
+ ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2] = type;
+ ((type_T **)seen_types->ga_data)[seen_types->ga_len * 2 + 1] = copy;
+ ++seen_types->ga_len;
+
+ if (copy->tt_member != NULL)
+ copy->tt_member = copy_type_deep_rec(copy->tt_member,
+ type_gap, seen_types);
+
+ if (type->tt_args != NULL)
+ for (int i = 0; i < type->tt_argcount; ++i)
+ copy->tt_args[i] = copy_type_deep_rec(copy->tt_args[i],
+ type_gap, seen_types);
+
+ return copy;
+ }
+
+ /*
+ * Make a deep copy of "type".
+ * When allocation fails returns "type".
+ */
+ static type_T *
+ copy_type_deep(type_T *type, garray_T *type_gap)
+ {
+ garray_T seen_types;
+ // stores type pairs : a type we have seen and the copy used
+ ga_init2(&seen_types, sizeof(type_T *) * 2, 20);
+
+ type_T *res = copy_type_deep_rec(type, type_gap, &seen_types);
+
+ ga_clear(&seen_types);
+ return res;
+ }
+
void
clear_type_list(garray_T *gap)
{
***************
*** 404,410 ****
|| (flags & TVTT_MORE_SPECIFIC) == 0
|| l->lv_type->tt_member != &t_any))
// make a copy, lv_type may be freed if the list is freed
! return copy_type(l->lv_type, type_gap);
if (l->lv_first == &range_list_item)
return &t_list_number;
if (l->lv_copyID == copyID)
--- 453,459 ----
|| (flags & TVTT_MORE_SPECIFIC) == 0
|| l->lv_type->tt_member != &t_any))
// make a copy, lv_type may be freed if the list is freed
! return copy_type_deep(l->lv_type, type_gap);
if (l->lv_first == &range_list_item)
return &t_list_number;
if (l->lv_copyID == copyID)
*** ../vim-9.0.1051/src/version.c 2022-12-13 12:26:04.855054169 +0000
--- src/version.c 2022-12-13 13:42:05.447546705 +0000
***************
*** 697,698 ****
--- 697,700 ----
{ /* Add new patch number below this line */
+ /**/
+ 1052,
/**/
--
DINGO: You must spank her well and after you have spanked her you
may deal with her as you like and then ... spank me.
AMAZING: And spank me!
STUNNER: And me.
LOVELY: And me.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///