]> granicus.if.org Git - vim/commitdiff
patch 8.2.2021: Vim9: get E1099 when autocommand resets did_emsg v8.2.2021
authorBram Moolenaar <Bram@vim.org>
Fri, 20 Nov 2020 18:26:48 +0000 (19:26 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 20 Nov 2020 18:26:48 +0000 (19:26 +0100)
Problem:    Vim9: get E1099 when autocommand resets did_emsg.
Solution:   Add did_emsg_cumul. (closes #7336)

src/ex_docmd.c
src/globals.h
src/testdir/test_vim9_func.vim
src/version.c
src/vim9execute.c

index dbaf21847d1863f14c642a2ddf2c8a76d5dde76e..a6bdac3abaa5ce7240bbe67667d12ee5fe13646a 100644 (file)
@@ -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)
        {
index dd7fa4a53179f14b6d9a11ef701eb4c81b9a05c4..af1a85c82a208ed8854a434969f6cc3544a78741 100644 (file)
@@ -230,6 +230,8 @@ EXTERN int  did_endif INIT(= FALSE);    // just had ":endif"
 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
index 5c937b65777c0a9029328a2edefd67ef8d571b05..7b5d3e9d7ea8621df37467db08041c34e4efb1fe 100644 (file)
@@ -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
index 4fdc0f1c85428ae1a91aa5223fb46f45e7718abf..aeadf361ad4f4eb036023f85f7ef914d1b5aa06c 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2021,
 /**/
     2020,
 /**/
index a7d83b47a70c7e9fffa79cc87dc4df5c9ec49f88..eca99f3aa2078be85d67d982ac5187b4df0124bc 100644 (file)
@@ -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);