]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1356: Vim9: crash when unletting variable v9.1.1356
authorHirohito Higashi <h.east.727@gmail.com>
Thu, 1 May 2025 06:56:39 +0000 (08:56 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 1 May 2025 06:56:39 +0000 (08:56 +0200)
Problem:  Vim9: crash when unletting variable
Solution: fix crash, allow to use :unlet
          (Hirohito Higashi)

closes: #17226

Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/proto/vim9compile.pro
src/testdir/test_vim9_assign.vim
src/version.c
src/vim9cmds.c
src/vim9compile.c

index 080a2ffaaf015daac880a68098040d8d72cd803b..6d91bc86a02b86fd911b58434bb8985fd2079606 100644 (file)
@@ -2,7 +2,6 @@
 int lookup_local(char_u *name, size_t len, lvar_T *lvar, cctx_T *cctx);
 int arg_exists(char_u *name, size_t len, int *idxp, type_T **type, int *gen_load_outer, cctx_T *cctx);
 void update_script_var_block_id(char_u *name, int block_id);
-int script_is_vim9(void);
 int script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack);
 int cctx_class_method_idx(cctx_T *cctx, char_u *name, size_t len, class_T **cl_ret);
 int cctx_class_member_idx(cctx_T *cctx, char_u *name, size_t len, class_T **cl_ret);
index 960dd7116f50b01176d2672c58a1b57b2b12d39f..3b0838430c85dd509f5f93933e86a09458b94fcd 100644 (file)
@@ -2499,12 +2499,11 @@ def Test_unlet()
   assert_false(exists('g:somevar'))
   unlet! g:somevar
 
-  # also works for script-local variable in legacy Vim script
-  s:somevar = 'legacy'
+  # script-local variable cannot be removed in Vim9 script
+  s:somevar = 'local'
   assert_true(exists('s:somevar'))
-  unlet s:somevar
-  assert_false(exists('s:somevar'))
-  unlet! s:somevar
+  v9.CheckDefExecFailure(['unlet s:somevar'], 'E1081:', 1)
+  v9.CheckDefExecFailure(['unlet! s:somevar'], 'E1081:', 1)
 
   if 0
     unlet g:does_not_exist
@@ -2677,13 +2676,21 @@ def Test_unlet()
    'enddef',
    'defcompile',
    ], 'E1081:')
-  v9.CheckScriptFailure([
+  v9.CheckScriptSuccess([
    'vim9script',
    'var svar = 123',
    'func Func()',
    '  unlet s:svar',
    'endfunc',
    'Func()',
+   ])
+  v9.CheckScriptFailure([
+   'vim9script',
+   'var svar = 123',
+   'def Func()',
+   '  vim9cmd unlet s:svar',
+   'enddef',
+   'defcompile',
    ], 'E1081:')
   v9.CheckScriptFailure([
    'vim9script',
index 0c731a88dd9833cfe6fef69770d7ba621e94e7f4..d82060838aee803ed5513219e06f63d7a993b242 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1356,
 /**/
     1355,
 /**/
index 6295090110824ca39f1816ce50e68136ced5b385..d4ffb9331307dbf275d10e854c14ab9db4590806 100644 (file)
@@ -99,7 +99,7 @@ check_vim9_unlet(char_u *name)
     if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL)
     {
        // "unlet s:var" is allowed in legacy script.
-       if (*name == 's' && !script_is_vim9())
+       if (*name == 's' && !in_vim9script())
            return OK;
        semsg(_(e_cannot_unlet_str), name);
        return FAIL;
index 0a4c3facb689c16af808b4a46cb7b8cf191144c7..b3cf86c98dac6a42e42b7e7a08c131987b9e0444 100644 (file)
@@ -287,15 +287,6 @@ update_script_var_block_id(char_u *name, int block_id)
     sav->sav_block_id = block_id;
 }
 
-/*
- * Return TRUE if the script context is Vim9 script.
- */
-    int
-script_is_vim9(void)
-{
-    return SCRIPT_ITEM(current_sctx.sc_sid)->sn_version == SCRIPT_VERSION_VIM9;
-}
-
 /*
  * Lookup a variable (without s: prefix) in the current script.
  * "cctx" is NULL at the script level, "cstack" is NULL in a function.
@@ -306,7 +297,7 @@ script_var_exists(char_u *name, size_t len, cctx_T *cctx, cstack_T *cstack)
 {
     if (current_sctx.sc_sid <= 0)
        return FAIL;
-    if (script_is_vim9())
+    if (current_script_is_vim9())
     {
        // Check script variables that were visible where the function was
        // defined.