patch 8.2.3933: after ":cd" fails ":cd -" is incorrect

Problem:    After ":cd" fails ":cd -" is incorrect.
Solution:   Set the previous directory only after successfully changing
            directory. (Richard Doty, closes #9419, closes #8983)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index d4c725c..8f4f4ae 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -7359,7 +7359,6 @@
 	int		forceit,
 	cdscope_T	scope)
 {
-    char_u	*tofree;
     char_u	*pdir = NULL;
     int		dir_differs;
     int		retval = FALSE;
@@ -7385,20 +7384,11 @@
 	new_dir = pdir;
     }
 
-    // Free the previous directory
-    tofree = get_prevdir(scope);
-
     // Save current directory for next ":cd -"
     if (mch_dirname(NameBuff, MAXPATHL) == OK)
 	pdir = vim_strsave(NameBuff);
     else
 	pdir = NULL;
-    if (scope == CDSCOPE_WINDOW)
-	curwin->w_prevdir = pdir;
-    else if (scope == CDSCOPE_TABPAGE)
-	curtab->tp_prevdir = pdir;
-    else
-	prev_dir = pdir;
 
     // For UNIX ":cd" means: go to home directory.
     // On other systems too if 'cdhome' is set.
@@ -7425,10 +7415,23 @@
     dir_differs = new_dir == NULL || pdir == NULL
 	|| pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
     if (new_dir == NULL || (dir_differs && vim_chdir(new_dir)))
+    {
 	emsg(_(e_failed));
+	vim_free(pdir);
+    }
     else
     {
 	char_u  *acmd_fname;
+	char_u	**pp;
+
+	if (scope == CDSCOPE_WINDOW)
+	    pp = &curwin->w_prevdir;
+	else if (scope == CDSCOPE_TABPAGE)
+	    pp = &curtab->tp_prevdir;
+	else
+	    pp = &prev_dir;
+	vim_free(*pp);
+	*pp = pdir;
 
 	post_chdir(scope);
 
@@ -7445,7 +7448,6 @@
 	}
 	retval = TRUE;
     }
-    vim_free(tofree);
 
     return retval;
 }
@@ -7565,9 +7567,9 @@
 # endif
 
     if (hide_cursor)
-        cursor_sleep();
+	cursor_sleep();
     else
-        cursor_on();
+	cursor_on();
 
     out_flush_cursor(FALSE, FALSE);
     while (!got_int && done < msec)
@@ -7619,7 +7621,7 @@
 	(void)vpeekc();
 
     if (hide_cursor)
-        cursor_unsleep();
+	cursor_unsleep();
 }
 
 /*
diff --git a/src/testdir/test_cd.vim b/src/testdir/test_cd.vim
index 566e9f6..c2217c9 100644
--- a/src/testdir/test_cd.vim
+++ b/src/testdir/test_cd.vim
@@ -44,6 +44,13 @@
   cd -
   call assert_equal(path, getcwd())
 
+  " Test for :cd - after a failed :cd
+  call assert_fails('cd /nonexistent', 'E344:')
+  call assert_equal(path, getcwd())
+  cd -
+  call assert_equal(path_dotdot, getcwd())
+  cd -
+
   " Test for :cd - without a previous directory
   let lines =<< trim [SCRIPT]
     call assert_fails('cd -', 'E186:')
diff --git a/src/version.c b/src/version.c
index bbfa0ff..2b1ce02 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3933,
+/**/
     3932,
 /**/
     3931,