Patch 8.2.2263
Problem:    Vim9: compilation error with try-catch in skipped block.
Solution:   Do not bail out when generate_instr() returns NULL. (closes #7584)
Files:      src/vim9compile.c, src/testdir/test_vim9_script.vim


*** ../vim-8.2.2262/src/vim9compile.c   2021-01-01 14:49:11.908956386 +0100
--- src/vim9compile.c   2021-01-01 16:04:51.228065012 +0100
***************
*** 6916,6926 ****
      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;
  
      // scope for the try block itself
      scope = new_scope(cctx, BLOCK_SCOPE);
--- 6916,6929 ----
      if (try_scope == 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,6978 ****
        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,
                                                    JUMP_ALWAYS, cctx) == FAIL)
!       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;
      }
  
      p = skipwhite(arg);
--- 6962,6984 ----
        return NULL;
      }
  
!     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;
  
!       // 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,7025 ****
            return NULL;
      }
  
!     if (generate_instr(cctx, ISN_CATCH) == NULL)
        return NULL;
  
      if (new_scope(cctx, BLOCK_SCOPE) == NULL)
--- 7025,7031 ----
            return NULL;
      }
  
!     if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_CATCH) == NULL)
        return NULL;
  
      if (new_scope(cctx, BLOCK_SCOPE) == NULL)
***************
*** 7097,7129 ****
        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);
  
!     // 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;
      }
  
      compile_endblock(cctx);
  
!     if (generate_instr(cctx, ISN_ENDTRY) == NULL)
        return NULL;
      return arg;
  }
--- 7103,7139 ----
        return NULL;
      }
  
!     if (cctx->ctx_skip != SKIP_YES)
      {
!       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);
! 
!       // 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;
!       }
      }
  
      compile_endblock(cctx);
  
!     if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_ENDTRY) == 
NULL)
        return NULL;
      return arg;
  }
*** ../vim-8.2.2262/src/testdir/test_vim9_script.vim    2020-12-31 
21:28:43.423217932 +0100
--- src/testdir/test_vim9_script.vim    2021-01-01 16:09:43.118910921 +0100
***************
*** 361,366 ****
--- 361,395 ----
    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]
*** ../vim-8.2.2262/src/version.c       2021-01-01 15:11:00.008727261 +0100
--- src/version.c       2021-01-01 15:59:30.649382341 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2263,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
75. You start wondering whether you could actually upgrade your brain
    with a Pentium Pro microprocessor 80.  The upgrade works just fine.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202101011511.101FBTWP1548684%40masaka.moolenaar.net.

Raspunde prin e-mail lui