Patch 9.0.1462
Problem:    Recursively calling :defer function if it does :qa.
Solution:   Clear the defer entry before calling the function. (closes #12266)
Files:      src/userfunc.c, src/testdir/test_user_func.vim


*** ../vim-9.0.1461/src/userfunc.c      2023-04-15 13:17:22.879094522 +0100
--- src/userfunc.c      2023-04-17 19:14:45.990924350 +0100
***************
*** 6096,6115 ****
  
      for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
      {
-       funcexe_T   funcexe;
-       typval_T    rettv;
        defer_T     *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
-       int         i;
  
        CLEAR_FIELD(funcexe);
        funcexe.fe_evaluate = TRUE;
  
        rettv.v_type = VAR_UNKNOWN;     // clear_tv() uses this
!       call_func(dr->dr_name, -1, &rettv,
!                                   dr->dr_argcount, dr->dr_argvars, &funcexe);
        clear_tv(&rettv);
!       vim_free(dr->dr_name);
!       for (i = dr->dr_argcount - 1; i >= 0; --i)
            clear_tv(&dr->dr_argvars[i]);
      }
      ga_clear(&funccal->fc_defer);
--- 6096,6122 ----
  
      for (idx = funccal->fc_defer.ga_len - 1; idx >= 0; --idx)
      {
        defer_T     *dr = ((defer_T *)funccal->fc_defer.ga_data) + idx;
  
+       if (dr->dr_name == NULL)
+           // already being called, can happen if function does ":qa"
+           continue;
+ 
+       funcexe_T   funcexe;
        CLEAR_FIELD(funcexe);
        funcexe.fe_evaluate = TRUE;
  
+       typval_T    rettv;
        rettv.v_type = VAR_UNKNOWN;     // clear_tv() uses this
! 
!       char_u *name = dr->dr_name;
!       dr->dr_name = NULL;
! 
!       call_func(name, -1, &rettv, dr->dr_argcount, dr->dr_argvars, &funcexe);
! 
        clear_tv(&rettv);
!       vim_free(name);
!       for (int i = dr->dr_argcount - 1; i >= 0; --i)
            clear_tv(&dr->dr_argvars[i]);
      }
      ga_clear(&funccal->fc_defer);
*** ../vim-9.0.1461/src/testdir/test_user_func.vim      2022-12-19 
20:28:34.061118368 +0000
--- src/testdir/test_user_func.vim      2023-04-17 19:21:58.522207983 +0100
***************
*** 656,661 ****
--- 656,662 ----
        vim9script
        func DeferLevelTwo()
          call writefile(['text'], 'XQuitallTwo', 'D')
+         call writefile(['quit'], 'XQuitallThree', 'a')
          qa!
        endfunc
  
***************
*** 671,676 ****
--- 672,680 ----
    call assert_equal(0, v:shell_error)
    call assert_false(filereadable('XQuitallOne'))
    call assert_false(filereadable('XQuitallTwo'))
+   call assert_equal(['quit'], readfile('XQuitallThree'))
+ 
+   call delete('XQuitallThree')
  endfunc
  
  func Test_defer_quitall_in_expr_func()
*** ../vim-9.0.1461/src/version.c       2023-04-17 16:40:54.728586072 +0100
--- src/version.c       2023-04-17 19:22:59.354107441 +0100
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1462,
  /**/

-- 
Citizens are not allowed to attend a movie house or theater nor ride in a
public streetcar within at least four hours after eating garlic.
                [real standing law in Indiana, United States of America]

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20230417182416.484431C042F%40moolenaar.net.

Raspunde prin e-mail lui