patch 9.1.0988: Vim9: no error when using uninitialized var in new() Commit: https://github.com/vim/vim/commit/b04af4cc9636ccbadc625e743a265a394bd48943 Author: Yegappan Lakshmanan <yegap...@yahoo.com> Date: Fri Jan 3 10:50:08 2025 +0100
patch 9.1.0988: Vim9: no error when using uninitialized var in new() Problem: Vim9: no error when using uninitialized var in new() (lifepillar, Aliaksei Budavei) Solution: Give an error if an uninitialized object variable is referenced in new() (Yegappan Lakshmanan) fixes: #14411 fixes: #16344 closes: #16374 Signed-off-by: Yegappan Lakshmanan <yegap...@yahoo.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/errors.h b/src/errors.h index 1e59597d9..ad36e33a6 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3616,8 +3616,10 @@ EXTERN char e_duplicate_enum_str[] INIT(= N_("E1428: Duplicate enum value: %s")); EXTERN char e_class_can_only_be_used_in_script[] INIT(= N_("E1429: Class can only be used in a script")); +EXTERN char e_uninitialized_object_var_reference[] + INIT(= N_("E1430: Uninitialized object variable '%s' referenced")); #endif -// E1429 - E1499 unused (reserved for Vim9 class support) +// E1431 - E1499 unused (reserved for Vim9 class support) EXTERN char e_cannot_mix_positional_and_non_positional_str[] INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s")); EXTERN char e_fmt_arg_nr_unused_str[] diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 4a7962a6c..c7a0fbefa 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -11723,4 +11723,120 @@ def Test_use_object_method_in_a_method_call() v9.CheckSourceFailure(lines, 'E1326: Variable "NewCost" not found in object "Foo"') enddef +" Test for referencing an object variable which is not yet initialized +def Test_uninitialized_object_var() + var lines =<< trim END + vim9script + class Foo + const two: number = Foo.Two(this) + const one: number = 1 + + static def Two(that: Foo): number + return that.one + 2 + enddef + endclass + + echo Foo.Two(Foo.new()) + END + v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'one' referenced") + + lines =<< trim END + vim9script + class Foo + const one: number = Foo.One(this) + + static def One(that: Foo): number + return 1 + enddef + endclass + + assert_equal(1, Foo.One(Foo.new())) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + class Foo + const one: number = 1 + const two: number = Foo.Two(this) + + static def Two(that: Foo): number + return that.one + 1 + enddef + endclass + + assert_equal(2, Foo.Two(Foo.new())) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + class Foo + const Id: func(any): any = ((_) => (v) => v)(this) + + static def Id(that: Foo): func(any): any + return that.Id + enddef + endclass + + assert_equal(5, Foo.Id(Foo.new())(5)) + assert_equal(7, Foo.new().Id(7)) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + class Foo + const Id: func(any): any = ((that) => (_) => that)(this) + + static def Id(that: Foo): func(any): any + return that.Id + enddef + endclass + + const Id0: func(any): any = Foo.Id(Foo.new()) + const Id1: func(any): any = Foo.new().Id + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + class Foo + const Id: any = Foo.Id(this) + + static def Id(that: Foo): any + return that.Id + enddef + endclass + + const Id2: any = Foo.Id(Foo.new()) + const Id3: any = Foo.new().Id + END + v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'Id' referenced") + + lines =<< trim END + vim9script + + class Foo + var x: string = '' + var Y: func(): string = () => this.x + endclass + + var foo = Foo.new('ok') + assert_equal('ok', foo.Y()) + END + v9.CheckSourceSuccess(lines) + + lines =<< trim END + vim9script + + class Foo + var x: string = this.x + endclass + + var foo = Foo.new('ok') + END + v9.CheckSourceFailure(lines, "E1430: Uninitialized object variable 'x' referenced") +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/version.c b/src/version.c index 1dbbca563..987aa9b3f 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 988, /**/ 987, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index de12d8e6a..dde95b511 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -4844,6 +4844,20 @@ exec_instructions(ectx_T *ectx) int arg_set = tv->v_type != VAR_UNKNOWN && !(tv->v_type == VAR_SPECIAL && tv->vval.v_number == VVAL_NONE); + + if (iptr->isn_type == ISN_JUMP_IF_ARG_NOT_SET && !arg_set) + { + dfunc_T *df = ((dfunc_T *)def_functions.ga_data) + + ectx->ec_dfunc_idx; + ufunc_T *ufunc = df->df_ufunc; + // jump_arg_off is negative for arguments + size_t argidx = ufunc->uf_def_args.ga_len + + iptr->isn_arg.jumparg.jump_arg_off + + STACK_FRAME_SIZE; + type_T *t = ufunc->uf_arg_types[argidx]; + tv->v_type = t->tt_type; + } + if (iptr->isn_type == ISN_JUMP_IF_ARG_SET ? arg_set : !arg_set) ectx->ec_iidx = iptr->isn_arg.jumparg.jump_where; break; @@ -5718,6 +5732,17 @@ exec_instructions(ectx_T *ectx) // The members are located right after the object struct. typval_T *mtv = ((typval_T *)(obj + 1)) + idx; + if (mtv->v_type == VAR_UNKNOWN) + { + // Referencing an object variable (without a type) + // which is not yet initialized. So the type is not + // yet known. + ocmember_T *m = &obj->obj_class->class_obj_members[idx]; + SOURCING_LNUM = iptr->isn_lnum; + semsg(_(e_uninitialized_object_var_reference), + m->ocm_name); + goto on_error; + } copy_tv(mtv, tv); // Unreference the object after getting the member, it may -- -- 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 vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1tTeTN-004dnb-6B%40256bit.org.