changeset 24097:26d3c1539bcc v8.2.2590

patch 8.2.2590: Vim9: default argument value may cause internal error Commit: https://github.com/vim/vim/commit/12bce95887f7c5f07a7bdb7b4485b53d074ccc0a Author: Bram Moolenaar <Bram@vim.org> Date: Thu Mar 11 20:04:04 2021 +0100 patch 8.2.2590: Vim9: default argument value may cause internal error Problem: Vim9: default argument value may cause internal error. Solution: Hide later function arguments when compiling the expression. (closes #7948)
author Bram Moolenaar <Bram@vim.org>
date Thu, 11 Mar 2021 20:15:05 +0100
parents 8c4686919942
children fd9439450dd5
files src/testdir/test_vim9_func.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 20 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -311,6 +311,14 @@ def Test_call_default_args()
   delfunc g:Func
   CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
   delfunc g:Func
+
+  var lines =<< trim END
+      vim9script
+      def Func(a = b == 0 ? 1 : 2, b = 0)
+      enddef
+      defcompile
+  END
+  CheckScriptFailure(lines, 'E1001: Variable not found: b')
 enddef
 
 def FuncWithComment(  # comment
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2590,
+/**/
     2589,
 /**/
     2588,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8199,6 +8199,7 @@ compile_def_function(
     {
 	int	count = ufunc->uf_def_args.ga_len;
 	int	first_def_arg = ufunc->uf_args.ga_len - count;
+	int	uf_args_len = ufunc->uf_args.ga_len;
 	int	i;
 	char_u	*arg;
 	int	off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
@@ -8211,16 +8212,24 @@ compile_def_function(
 	ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1);
 	if (ufunc->uf_def_arg_idx == NULL)
 	    goto erret;
+	SOURCING_LNUM = 0;  // line number unknown
 	for (i = 0; i < count; ++i)
 	{
 	    garray_T	*stack = &cctx.ctx_type_stack;
 	    type_T	*val_type;
 	    int		arg_idx = first_def_arg + i;
 	    where_T	where;
+	    int		r;
+
+	    // Make sure later arguments are not found.
+	    ufunc->uf_args.ga_len = i;
 
 	    ufunc->uf_def_arg_idx[i] = instr->ga_len;
 	    arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
-	    if (compile_expr0(&arg, &cctx) == FAIL)
+	    r = compile_expr0(&arg, &cctx);
+
+	    ufunc->uf_args.ga_len = uf_args_len;
+	    if (r == FAIL)
 		goto erret;
 
 	    // If no type specified use the type of the default value.