From 7dad6e887e6cadfcfda4b3f2054653116763afb5 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 5 Apr 2025 12:59:28 -0300 Subject: [PATCH] parser,checker,cgen: fix wrong auto heap deref of auto `index` loop var (fix #24117) (#24124) --- vlib/v/ast/ast.v | 1 + vlib/v/checker/checker.v | 2 +- vlib/v/gen/c/cgen.v | 3 ++- vlib/v/parser/containers.v | 11 ++++++----- vlib/v/tests/interfaces/interface_arr_init_test.v | 6 ++++++ 5 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 vlib/v/tests/interfaces/interface_arr_init_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index d768df059..49004758f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -901,6 +901,7 @@ pub mut: is_arg bool // fn args should not be autofreed is_auto_deref bool is_unwrapped bool // ct type smartcast unwrapped + is_index_var bool // index loop var expr Expr typ Type orig_type Type // original sumtype type; 0 if it's not a sumtype diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 488821c7f..bfb3520f5 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3490,7 +3490,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { } else if !from_type.has_option_or_result() && mut to_sym.info is ast.Interface { if c.type_implements(from_type, to_type, node.pos) { if !from_type.is_any_kind_of_pointer() && from_sym.kind != .interface - && !c.inside_unsafe { + && !c.inside_unsafe && !from_type.is_number() { c.mark_as_referenced(mut &node.expr, true) } if to_sym.info.is_generic { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 4db024185..92dc01900 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2814,7 +2814,8 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty && (expr.expr is ast.ArrayInit && expr.expr.is_fixed) if !is_cast_fixed_array_init && (is_comptime_variant || !expr.is_lvalue() - || (expr is ast.Ident && expr.obj.is_simple_define_const())) { + || (expr is ast.Ident && (expr.obj.is_simple_define_const() + || (expr.obj is ast.Var && expr.obj.is_index_var)))) { // Note: the `_to_sumtype_` family of functions do call memdup internally, making // another duplicate with the HEAP macro is redundant, so use ADDR instead: if expr.is_as_cast() { diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index aec3ea9f6..0dfef0ab8 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -267,11 +267,12 @@ fn (mut p Parser) map_init() ast.MapInit { fn (mut p Parser) scope_register_index() { p.scope.objects['index'] = ast.Var{ // override index variable if it already exist, else create index variable - name: 'index' - pos: p.tok.pos() - typ: ast.int_type - is_mut: false - is_used: false + name: 'index' + pos: p.tok.pos() + typ: ast.int_type + is_mut: false + is_used: false + is_index_var: true } p.scope.objects['it'] = ast.Var{ // it is now deprecated, will be removed in future stable release name: 'it' diff --git a/vlib/v/tests/interfaces/interface_arr_init_test.v b/vlib/v/tests/interfaces/interface_arr_init_test.v new file mode 100644 index 000000000..9792a73f6 --- /dev/null +++ b/vlib/v/tests/interfaces/interface_arr_init_test.v @@ -0,0 +1,6 @@ +interface Values {} + +fn test_main() { + a := []Values{len: 4, init: Values(index)} + assert '${a}' == '[Values(0), Values(1), Values(2), Values(3)]' +} -- 2.39.5