To: vim_dev@googlegroups.com Subject: Patch 9.0.1119 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1119 Problem: Type of arguments not checked when calling a partial. Solution: Give an error for a wrong argument type. (closes #11753) Files: src/vim9execute.c, src/testdir/test_vim9_func.vim *** ../vim-9.0.1118/src/vim9execute.c 2022-12-29 20:56:20.025538293 +0000 --- src/vim9execute.c 2022-12-31 13:54:32.586955681 +0000 *************** *** 377,382 **** --- 377,417 ---- } /* + * Check "argcount" arguments on the stack against what "ufunc" expects. + * "off" is the offset of arguments on the stack. + * Return OK or FAIL. + */ + static int + check_ufunc_arg_types(ufunc_T *ufunc, int argcount, int off, ectx_T *ectx) + { + if (ufunc->uf_arg_types != NULL || ufunc->uf_va_type != NULL) + { + typval_T *argv = STACK_TV_BOT(0) - argcount - off; + + // The function can change at runtime, check that the argument + // types are correct. + for (int i = 0; i < argcount; ++i) + { + type_T *type = NULL; + + // assume a v:none argument, using the default value, is always OK + if (argv[i].v_type == VAR_SPECIAL + && argv[i].vval.v_number == VVAL_NONE) + continue; + + if (i < ufunc->uf_args.ga_len && ufunc->uf_arg_types != NULL) + type = ufunc->uf_arg_types[i]; + else if (ufunc->uf_va_type != NULL) + type = ufunc->uf_va_type->tt_member; + if (type != NULL && check_typval_arg_type(type, + &argv[i], NULL, i + 1) == FAIL) + return FAIL; + } + } + return OK; + } + + /* * Call compiled function "cdf_idx" from compiled code. * This adds a stack frame and sets the instruction pointer to the start of the * called function. *************** *** 498,503 **** --- 533,542 ---- return FAIL; } + // Check the argument types. + if (check_ufunc_arg_types(ufunc, argcount, vararg_count, ectx) == FAIL) + return FAIL; + // Reserve space for: // - missing arguments // - stack frame *************** *** 1345,1370 **** if (ufunc != NULL) { ! if (ufunc->uf_arg_types != NULL || ufunc->uf_va_type != NULL) ! { ! int i; ! typval_T *argv = STACK_TV_BOT(0) - argcount; ! ! // The function can change at runtime, check that the argument ! // types are correct. ! for (i = 0; i < argcount; ++i) ! { ! type_T *type = NULL; ! ! if (i < ufunc->uf_args.ga_len && ufunc->uf_arg_types != NULL) ! type = ufunc->uf_arg_types[i]; ! else if (ufunc->uf_va_type != NULL) ! type = ufunc->uf_va_type->tt_member; ! if (type != NULL && check_typval_arg_type(type, ! &argv[i], NULL, i + 1) == FAIL) ! return FAIL; ! } ! } return call_ufunc(ufunc, NULL, argcount, ectx, iptr, selfdict); } --- 1384,1391 ---- if (ufunc != NULL) { ! if (check_ufunc_arg_types(ufunc, argcount, 0, ectx) == FAIL) ! return FAIL; return call_ufunc(ufunc, NULL, argcount, ectx, iptr, selfdict); } *** ../vim-9.0.1118/src/testdir/test_vim9_func.vim 2022-12-27 17:24:55.270083348 +0000 --- src/testdir/test_vim9_func.vim 2022-12-31 13:59:36.086769681 +0000 *************** *** 4277,4282 **** --- 4277,4308 ---- bw! endfunc + def Test_lambda_argument_type_check() + var lines =<< trim END + vim9script + + def Scan(ll: list): func(func(any)) + return (Emit: func(any)) => { + for e in ll + Emit(e) + endfor + } + enddef + + def Sum(Cont: func(func(any))): any + var sum = 0.0 + Cont((v: float) => { # <== NOTE: the lambda expects a float + sum += v + }) + return sum + enddef + + const ml = [3.0, 2, 7] + echo Scan(ml)->Sum() + END + v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected float but got number') + enddef + def Test_multiple_funcref() # This was using a NULL pointer var lines =<< trim END *** ../vim-9.0.1118/src/version.c 2022-12-31 11:44:51.549772464 +0000 --- src/version.c 2022-12-31 13:33:14.947608978 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1119, /**/ -- So when I saw the post to comp.editors, I rushed over to the FTP site to grab it. So I yank apart the tarball, light x candles, where x= the vim version multiplied by the md5sum of the source divided by the MAC of my NIC (8A3FA78155A8A1D346C3C4A), put on black robes, dim the lights, wave a dead chicken over the hard drive, and summon the power of GNU GCC with the magic words "make config ; make!". [Jason Spence, compiling Vim 5.0] /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///