From 877149b8e0150c88645d260ba500a607f4013e87 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Mar 2026 00:09:58 +0300 Subject: [PATCH] cgen: fix error for value := &(m[key]) with map values (fixes #15115) --- vlib/v/gen/c/index.v | 12 +++++++++++- .../unsafe_pointers_to_map_values_test.v | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/vlib/v/gen/c/index.v b/vlib/v/gen/c/index.v index 9a94a7514..a6f688f9d 100644 --- a/vlib/v/gen/c/index.v +++ b/vlib/v/gen/c/index.v @@ -574,6 +574,12 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) { } if gen_or { g.writeln(';') + // The surrounding expression may already carry a pointer prefix placeholder. + direct_ptr_cur_line := if cur_line.ends_with('&') || cur_line.ends_with('H') { + cur_line[..cur_line.len - 1] + } else { + cur_line + } if g.unsafe_level > 0 && !node.is_option && !node.is_setter && node.or_expr.kind == .block && node.or_expr.stmts.len == 1 { last_stmt := node.or_expr.stmts[0] @@ -582,7 +588,11 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) { g.write('if (!${tmp_opt_ptr}) { ${tmp_opt_ptr} = ') g.expr(last_stmt.expr) g.write('; }') - g.write('\n${cur_line}(*${tmp_opt_ptr})') + if cur_line.ends_with('&') || cur_line.ends_with('H') { + g.write('\n${direct_ptr_cur_line}${tmp_opt_ptr}') + } else { + g.write('\n${cur_line}(*${tmp_opt_ptr})') + } return } } diff --git a/vlib/v/tests/builtin_maps/unsafe_pointers_to_map_values_test.v b/vlib/v/tests/builtin_maps/unsafe_pointers_to_map_values_test.v index d5df26101..9d38870c9 100644 --- a/vlib/v/tests/builtin_maps/unsafe_pointers_to_map_values_test.v +++ b/vlib/v/tests/builtin_maps/unsafe_pointers_to_map_values_test.v @@ -9,6 +9,11 @@ mut: mymap map[string]MyObject } +struct ArrayDefaultObject { +mut: + xs []u8 = []u8{len: 12, init: 0} +} + fn test_codegen_for_unsafe_pointers_to_map_values() { mut inst := Abc{} inst.mymap['abc'] = MyObject{123, 'abc'} @@ -39,3 +44,15 @@ fn test_codegen_for_unsafe_pointers_to_map_values() { assert inst.mymap['abc'].x == 999 assert inst.mymap['abc'].s == 'xyz' } + +fn test_codegen_for_unsafe_pointers_to_map_values_with_array_defaults() { + mut values := map[string]ArrayDefaultObject{} + mut missing := unsafe { &values['missing'] or { nil } } + assert missing == unsafe { nil } + values['abc'] = ArrayDefaultObject{} + mut value := unsafe { &values['abc'] or { nil } } + assert value != unsafe { nil } + assert value.xs.len == 12 + value.xs[0] = 7 + assert values['abc'].xs[0] == 7 +} -- 2.39.5