]> granicus.if.org Git - vim/commitdiff
patch 8.2.2263: Vim9: compilation error with try-catch in skipped block v8.2.2263
authorBram Moolenaar <Bram@vim.org>
Fri, 1 Jan 2021 15:10:46 +0000 (16:10 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 1 Jan 2021 15:10:46 +0000 (16:10 +0100)
Problem:    Vim9: compilation error with try-catch in skipped block.
Solution:   Do not bail out when generate_instr() returns NULL. (closes #7584)

src/testdir/test_vim9_script.vim
src/version.c
src/vim9compile.c

index 3fbf1bc32fd3905245ab81a67c1a05d6fd566ba1..d9aa71e268b18975269625b55ece2879418859f1 100644 (file)
@@ -361,6 +361,35 @@ def Test_try_catch()
   endtry
   assert_equal(99, n)
 
+  var done = 'no'
+  if 0
+    try | catch | endtry
+  else
+    done = 'yes'
+  endif
+  assert_equal('yes', done)
+
+  done = 'no'
+  if 1
+    done = 'yes'
+  else
+    try | catch | endtry
+    done = 'never'
+  endif
+  assert_equal('yes', done)
+
+  if 1
+  else
+    try | catch /pat/ | endtry
+    try | catch /pat/ 
+    endtry
+    try 
+    catch /pat/ | endtry
+    try 
+    catch /pat/ 
+    endtry
+  endif
+
   try
     # string slice returns a string, not a number
     n = g:astring[3]
index ceea2777f525feb6598a46d36bcd2b5a99438a87..26c9d8bf8dbcc197277b31f7f8d1552666b9fe0d 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2263,
 /**/
     2262,
 /**/
index d44fe487c64771e9c38d9cc4ceb9326e98b2bcc6..045061e1c8529a1148412de9f322c773c64e0b21 100644 (file)
@@ -6916,11 +6916,14 @@ compile_try(char_u *arg, cctx_T *cctx)
     if (try_scope == NULL)
        return NULL;
 
-    // "catch" is set when the first ":catch" is found.
-    // "finally" is set when ":finally" or ":endtry" is found
-    try_scope->se_u.se_try.ts_try_label = instr->ga_len;
-    if (generate_instr(cctx, ISN_TRY) == NULL)
-       return NULL;
+    if (cctx->ctx_skip != SKIP_YES)
+    {
+       // "catch" is set when the first ":catch" is found.
+       // "finally" is set when ":finally" or ":endtry" is found
+       try_scope->se_u.se_try.ts_try_label = instr->ga_len;
+       if (generate_instr(cctx, ISN_TRY) == NULL)
+           return NULL;
+    }
 
     // scope for the try block itself
     scope = new_scope(cctx, BLOCK_SCOPE);
@@ -6959,20 +6962,23 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
        return NULL;
     }
 
-    // Jump from end of previous block to :finally or :endtry
-    if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
+    if (cctx->ctx_skip != SKIP_YES)
+    {
+       // Jump from end of previous block to :finally or :endtry
+       if (compile_jump_to_end(&scope->se_u.se_try.ts_end_label,
                                                    JUMP_ALWAYS, cctx) == FAIL)
-       return NULL;
+           return NULL;
 
-    // End :try or :catch scope: set value in ISN_TRY instruction
-    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
-    if (isn->isn_arg.try.try_catch == 0)
-       isn->isn_arg.try.try_catch = instr->ga_len;
-    if (scope->se_u.se_try.ts_catch_label != 0)
-    {
-       // Previous catch without match jumps here
-       isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
-       isn->isn_arg.jump.jump_where = instr->ga_len;
+       // End :try or :catch scope: set value in ISN_TRY instruction
+       isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
+       if (isn->isn_arg.try.try_catch == 0)
+           isn->isn_arg.try.try_catch = instr->ga_len;
+       if (scope->se_u.se_try.ts_catch_label != 0)
+       {
+           // Previous catch without match jumps here
+           isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
+           isn->isn_arg.jump.jump_where = instr->ga_len;
+       }
     }
 
     p = skipwhite(arg);
@@ -7019,7 +7025,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
            return NULL;
     }
 
-    if (generate_instr(cctx, ISN_CATCH) == NULL)
+    if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL)
        return NULL;
 
     if (new_scope(cctx, BLOCK_SCOPE) == NULL)
@@ -7097,33 +7103,37 @@ compile_endtry(char_u *arg, cctx_T *cctx)
        return NULL;
     }
 
-    isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
-    if (isn->isn_arg.try.try_catch == 0 && isn->isn_arg.try.try_finally == 0)
+    if (cctx->ctx_skip != SKIP_YES)
     {
-       emsg(_(e_missing_catch_or_finally));
-       return NULL;
-    }
+       isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_try_label;
+       if (isn->isn_arg.try.try_catch == 0
+                                         && isn->isn_arg.try.try_finally == 0)
+       {
+           emsg(_(e_missing_catch_or_finally));
+           return NULL;
+       }
 
-    // Fill in the "end" label in jumps at the end of the blocks, if not done
-    // by ":finally".
-    compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
+       // Fill in the "end" label in jumps at the end of the blocks, if not
+       // done by ":finally".
+       compile_fill_jump_to_end(&scope->se_u.se_try.ts_end_label, cctx);
 
-    // End :catch or :finally scope: set value in ISN_TRY instruction
-    if (isn->isn_arg.try.try_catch == 0)
-       isn->isn_arg.try.try_catch = instr->ga_len;
-    if (isn->isn_arg.try.try_finally == 0)
-       isn->isn_arg.try.try_finally = instr->ga_len;
+       // End :catch or :finally scope: set value in ISN_TRY instruction
+       if (isn->isn_arg.try.try_catch == 0)
+           isn->isn_arg.try.try_catch = instr->ga_len;
+       if (isn->isn_arg.try.try_finally == 0)
+           isn->isn_arg.try.try_finally = instr->ga_len;
 
-    if (scope->se_u.se_try.ts_catch_label != 0)
-    {
-       // Last catch without match jumps here
-       isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
-       isn->isn_arg.jump.jump_where = instr->ga_len;
+       if (scope->se_u.se_try.ts_catch_label != 0)
+       {
+           // Last catch without match jumps here
+           isn = ((isn_T *)instr->ga_data) + scope->se_u.se_try.ts_catch_label;
+           isn->isn_arg.jump.jump_where = instr->ga_len;
+       }
     }
 
     compile_endblock(cctx);
 
-    if (generate_instr(cctx, ISN_ENDTRY) == NULL)
+    if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == NULL)
        return NULL;
     return arg;
 }