changeset 22948:707b90980de5 v8.2.2021

patch 8.2.2021: Vim9: get E1099 when autocommand resets did_emsg Commit: https://github.com/vim/vim/commit/eeece9e4885df6190d2615b199efa2b1d22c4bdb Author: Bram Moolenaar <Bram@vim.org> Date: Fri Nov 20 19:26:48 2020 +0100 patch 8.2.2021: Vim9: get E1099 when autocommand resets did_emsg Problem: Vim9: get E1099 when autocommand resets did_emsg. Solution: Add did_emsg_cumul. (closes https://github.com/vim/vim/issues/7336)
author Bram Moolenaar <Bram@vim.org>
date Fri, 20 Nov 2020 19:30:03 +0100
parents 8625a16d18dc
children a695c4f79964
files src/ex_docmd.c src/globals.h src/testdir/test_vim9_func.vim src/version.c src/vim9execute.c
diffstat 5 files changed, 37 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -747,6 +747,9 @@ do_cmdline(
      * cancel the whole command line, and any if/endif or loop.
      * If force_abort is set, we cancel everything.
      */
+#ifdef FEAT_EVAL
+    did_emsg_cumul += did_emsg;
+#endif
     did_emsg = FALSE;
 
     /*
@@ -778,7 +781,12 @@ do_cmdline(
 		&& !(getline_is_func && func_has_abort(real_cookie))
 #endif
 							)
+	{
+#ifdef FEAT_EVAL
+	    did_emsg_cumul += did_emsg;
+#endif
 	    did_emsg = FALSE;
+	}
 
 	/*
 	 * 1. If repeating a line in a loop, get a line from lines_ga.
@@ -1026,7 +1034,10 @@ do_cmdline(
 	if (did_emsg && !force_abort
 		&& getline_equal(fgetline, cookie, get_func_line)
 					      && !func_has_abort(real_cookie))
+	{
+	    // did_emsg_cumul is not set here
 	    did_emsg = FALSE;
+	}
 
 	if (cstack.cs_looplevel > 0)
 	{
--- a/src/globals.h
+++ b/src/globals.h
@@ -230,6 +230,8 @@ EXTERN int	did_endif INIT(= FALSE);    /
 EXTERN int	did_emsg;		    // set by emsg() when the message
 					    // is displayed or thrown
 #ifdef FEAT_EVAL
+EXTERN int	did_emsg_cumul;		    // cumulative did_emsg, increased
+					    // when did_emsg is reset.
 EXTERN int	called_vim_beep;	    // set if vim_beep() is called
 EXTERN int	did_uncaught_emsg;	    // emsg() was called and did not
 					    // cause an exception
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -1704,5 +1704,19 @@ def Test_block_scoped_var()
   CheckScriptSuccess(lines)
 enddef
 
+def Test_reset_did_emsg()
+  var lines =<< trim END
+      @s = 'blah'
+      au BufWinLeave * #
+      def Func()
+        var winid = popup_create('popup', {})
+        exe '*s'
+        popup_close(winid)
+      enddef
+      Func()
+  END
+  CheckScriptFailure(lines, 'E492:', 8)
+enddef
+
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2021,
+/**/
     2020,
 /**/
     2019,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -833,7 +833,7 @@ call_def_function(
     int		defcount = ufunc->uf_args.ga_len - argc;
     sctx_T	save_current_sctx = current_sctx;
     int		breakcheck_count = 0;
-    int		did_emsg_before = did_emsg;
+    int		did_emsg_before = did_emsg_cumul + did_emsg;
     int		save_suppress_errthrow = suppress_errthrow;
     msglist_T	**saved_msg_list = NULL;
     msglist_T	*private_msg_list = NULL;
@@ -859,7 +859,7 @@ call_def_function(
 	    || (ufunc->uf_def_status == UF_TO_BE_COMPILED
 			  && compile_def_function(ufunc, FALSE, NULL) == FAIL))
     {
-	if (did_emsg == did_emsg_before)
+	if (did_emsg_cumul + did_emsg == did_emsg_before)
 	    semsg(_(e_function_is_not_compiled_str),
 						   printable_func_name(ufunc));
 	return FAIL;
@@ -1086,13 +1086,10 @@ call_def_function(
 	    // execute Ex command line
 	    case ISN_EXEC:
 		{
-		    int save_did_emsg = did_emsg;
-
 		    SOURCING_LNUM = iptr->isn_lnum;
 		    do_cmdline_cmd(iptr->isn_arg.string);
-		    // do_cmdline_cmd() will reset did_emsg, but we want to
-		    // keep track of the count to compare with did_emsg_before.
-		    did_emsg += save_did_emsg;
+		    if (did_emsg)
+			goto on_error;
 		}
 		break;
 
@@ -1211,6 +1208,8 @@ call_def_function(
 			{
 			    SOURCING_LNUM = iptr->isn_lnum;
 			    do_cmdline_cmd((char_u *)ga.ga_data);
+			    if (did_emsg)
+				goto on_error;
 			}
 			else
 			{
@@ -2894,7 +2893,7 @@ func_return:
 
 on_error:
 	// If "emsg_silent" is set then ignore the error.
-	if (did_emsg == did_emsg_before && emsg_silent)
+	if (did_emsg_cumul + did_emsg == did_emsg_before && emsg_silent)
 	    continue;
 
 	// If we are not inside a try-catch started here, abort execution.
@@ -2952,7 +2951,7 @@ failed_early:
     // Not sure if this is necessary.
     suppress_errthrow = save_suppress_errthrow;
 
-    if (ret != OK && did_emsg == did_emsg_before)
+    if (ret != OK && did_emsg_cumul + did_emsg == did_emsg_before)
 	semsg(_(e_unknown_error_while_executing_str),
 						   printable_func_name(ufunc));
     funcdepth_restore(orig_funcdepth);