On So, 25 Jun 2017, Bram Moolenaar wrote:

> 
> Patch 8.0.0678
> Problem:    When 'equalalways' is set and closing a window in a separate
>             frame, not all window sizes are adjusted. (Glacambre)
> Solution:   Resize all windows if the new current window is not in the same
>             frame as the closed window. (closes #1707)
> Files:      src/window.c, src/testdir/test_window_cmd.vim

>       if (p_ea && (*p_ead == 'b' || *p_ead == dir))
> !     /* If the frame of the closed window contains the new current window,
> !      * only resize that frame.  Otherwise resize all windows. */
> !     win_equal(curwin,
> !                   curwin->w_frame->fr_parent == win_frame->fr_parent, dir);

This cannot be completely correct. win_frame->fr_parent is already freed 
at window.c:2424 at win_free_mem(), so here we are accessing freed 
memory and I think this is the reason for the build failures at travis 
and appveyor.

How about the attached patch, which delays freeing the framepointer in 
case of 'equalalways'?

Best,
Christian
-- 
Lieber an der Spitze stehen, als auf die Spitze treiben.

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/window.c b/src/window.c
index 8078e011d..e9b601529 100644
--- a/src/window.c
+++ b/src/window.c
@@ -23,7 +23,7 @@ static void win_totop(int size, int flags);
 static void win_equal_rec(win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height);
 static int last_window(void);
 static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_curtab);
-static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp);
+static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp, int ea);
 static frame_T *win_altframe(win_T *win, tabpage_T *tp);
 static tabpage_T *alt_tabpage(void);
 static win_T *frame2win(frame_T *frp);
@@ -2283,6 +2283,7 @@ win_close(win_T *win, int free_buf)
     int		help_window = FALSE;
     tabpage_T   *prev_curtab = curtab;
     frame_T	*win_frame = win->w_frame;
+    int         equalalways;
 
     if (last_window())
     {
@@ -2421,7 +2422,8 @@ win_close(win_T *win, int free_buf)
 
     /* Free the memory used for the window and get the window that received
      * the screen space. */
-    wp = win_free_mem(win, &dir, NULL);
+    equalalways = p_ea && (*p_ead == 'b' || *p_ead == dir);
+    wp = win_free_mem(win, &dir, NULL, equalalways);
 
     /* Make sure curwin isn't invalid.  It can cause severe trouble when
      * printing an error message.  For win_equal() curbuf needs to be valid
@@ -2459,11 +2461,15 @@ win_close(win_T *win, int free_buf)
 	 * using the window. */
 	check_cursor();
     }
-    if (p_ea && (*p_ead == 'b' || *p_ead == dir))
+    if (equalalways)
+    {
 	/* If the frame of the closed window contains the new current window,
 	 * only resize that frame.  Otherwise resize all windows. */
 	win_equal(curwin,
 		      curwin->w_frame->fr_parent == win_frame->fr_parent, dir);
+	/* can be freed now */
+	vim_free(win_frame);
+    }
     else
 	win_comp_pos();
     if (close_curwin)
@@ -2558,7 +2564,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
     }
 
     /* Free the memory used for the window. */
-    win_free_mem(win, &dir, tp);
+    win_free_mem(win, &dir, tp, FALSE);
 
     if (free_tp)
 	free_tabpage(tp);
@@ -2572,7 +2578,8 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
 win_free_mem(
     win_T	*win,
     int		*dirp,		/* set to 'v' or 'h' for direction if 'ea' */
-    tabpage_T	*tp)		/* tab page "win" is in, NULL for current */
+    tabpage_T	*tp,		/* tab page "win" is in, NULL for current */
+    int         dont_free)	/* if TRUE, then do not free the frame pointer yet */
 {
     frame_T	*frp;
     win_T	*wp;
@@ -2580,7 +2587,8 @@ win_free_mem(
     /* Remove the window and its frame from the tree of frames. */
     frp = win->w_frame;
     wp = winframe_remove(win, dirp, tp);
-    vim_free(frp);
+    if (!dont_free)
+	vim_free(frp);
     win_free(win, tp);
 
     /* When deleting the current window of another tab page select a new
@@ -2605,13 +2613,13 @@ win_free_all(void)
 # ifdef FEAT_AUTOCMD
     if (aucmd_win != NULL)
     {
-	(void)win_free_mem(aucmd_win, &dummy, NULL);
+	(void)win_free_mem(aucmd_win, &dummy, NULL, FALSE);
 	aucmd_win = NULL;
     }
 # endif
 
     while (firstwin != NULL)
-	(void)win_free_mem(firstwin, &dummy, NULL);
+	(void)win_free_mem(firstwin, &dummy, NULL, FALSE);
 
     /* No window should be used after this. Set curwin to NULL to crash
      * instead of using freed memory. */

Raspunde prin e-mail lui