]> granicus.if.org Git - vim/commitdiff
patch 8.2.3099: Vim9: missing catch/finally not reported at script level v8.2.3099
authorBram Moolenaar <Bram@vim.org>
Sun, 4 Jul 2021 12:47:30 +0000 (14:47 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 4 Jul 2021 12:47:30 +0000 (14:47 +0200)
Problem:    Vim9: missing catch/finally not reported at script level.
Solution:   Give an error. (closes #8487)

src/ex_eval.c
src/structs.h
src/testdir/test_vim9_script.vim
src/version.c

index d68e792449f09477093962ce248d5cf9008f2371..dac70ab3ace06329d7385757e059322fb0b4f54a 100644 (file)
@@ -1670,6 +1670,8 @@ ex_catch(exarg_T *eap)
        for (idx = cstack->cs_idx; idx > 0; --idx)
            if (cstack->cs_flags[idx] & CSF_TRY)
                break;
+       if (cstack->cs_flags[idx] & CSF_TRY)
+           cstack->cs_flags[idx] |= CSF_CATCH;
        if (cstack->cs_flags[idx] & CSF_FINALLY)
        {
            // Give up for a ":catch" after ":finally" and ignore it.
@@ -1963,8 +1965,8 @@ ex_endtry(exarg_T *eap)
         * made inactive by a ":continue", ":break", ":return", or ":finish" in
         * the finally clause.  The latter case need not be tested since then
         * anything pending has already been discarded. */
-       skip = did_emsg || got_int || did_throw ||
-           !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
+       skip = did_emsg || got_int || did_throw
+                            || !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
 
        if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
        {
@@ -1992,6 +1994,14 @@ ex_endtry(exarg_T *eap)
        {
            idx = cstack->cs_idx;
 
+           if (in_vim9script()
+                    && (cstack->cs_flags[idx] & (CSF_CATCH|CSF_FINALLY)) == 0)
+           {
+               // try/endtry without any catch or finally: give an error and
+               // continue.
+               eap->errmsg = _(e_missing_catch_or_finally);
+           }
+
            /*
             * If we stopped with the exception currently being thrown at this
             * try conditional since we didn't know that it doesn't have
index be4082b93524a2f8139890ee495e29ba14674786..f1f8f32583fdb3511fc8f7dd0bc899635b386406 100644 (file)
@@ -936,13 +936,14 @@ typedef struct {
 
 # define CSF_TRY       0x0100  // is a ":try"
 # define CSF_FINALLY   0x0200  // ":finally" has been passed
-# define CSF_THROWN    0x0400  // exception thrown to this try conditional
-# define CSF_CAUGHT    0x0800  // exception caught by this try conditional
-# define CSF_SILENT    0x1000  // "emsg_silent" reset by ":try"
+# define CSF_CATCH     0x0400  // ":catch" has been seen
+# define CSF_THROWN    0x0800  // exception thrown to this try conditional
+# define CSF_CAUGHT    0x1000  // exception caught by this try conditional
+# define CSF_SILENT    0x2000  // "emsg_silent" reset by ":try"
 // Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
 // (an ":if"), and CSF_SILENT is only used when CSF_TRY is set.
 //
-#define CSF_FUNC_DEF   0x2000  // a function was defined in this block
+#define CSF_FUNC_DEF   0x4000  // a function was defined in this block
 
 /*
  * What's pending for being reactivated at the ":endtry" of this try
index dfb1a41bb1a4474df5e6b358b4afd3000d6c04da..9cf098917c0151cf7581e7a7c58d4d4d884113c7 100644 (file)
@@ -603,6 +603,15 @@ def Test_try_catch_throw()
   CheckScriptSuccess(lines)
   assert_match('E808: Number or Float required', g:caught)
   unlet g:caught
+
+  # missing catch and/or finally
+  lines =<< trim END
+      vim9script
+      try
+        echo 'something'
+      endtry
+  END
+  CheckScriptFailure(lines, 'E1032:')
 enddef
 
 def Test_try_in_catch()
index 8d391d331d5af43fb1022d8ae390d5146b0b405c..062e856e04a31978b8e65c2492328d851cbf291c 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3099,
 /**/
     3098,
 /**/