From 3934e4aa8c04d4fe68641f6974e8e2877faed474 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Feb 2026 22:12:17 +0300 Subject: [PATCH] cgen: fix invalid C code generated (fixes #17200) --- vlib/v/gen/c/fn.v | 9 ++++++++- .../string_index_method_ptr_receiver.c.must_have | 1 + .../v/gen/c/testdata/string_index_method_ptr_receiver.vv | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 vlib/v/gen/c/testdata/string_index_method_ptr_receiver.c.must_have create mode 100644 vlib/v/gen/c/testdata/string_index_method_ptr_receiver.vv diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 4d52cd011..0a632c07b 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1797,13 +1797,20 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } is_interface := left_sym.kind == .interface && g.table.sym(node.receiver_type).kind == .interface + mut receiver_expr_is_addressable := node.left.is_lvalue() + if node.left is ast.IndexExpr && node.left.left_type != 0 { + indexed_container_sym := g.table.final_sym(g.unwrap_generic(node.left.left_type)) + if indexed_container_sym.kind == .string && !node.left.left_type.is_ptr() { + receiver_expr_is_addressable = false + } + } if node.receiver_type.is_ptr() && (!left_type.is_ptr() || node.from_embed_types.len != 0 || (left_type.has_flag(.shared_f) && node.kind != .str)) { // The receiver is a reference, but the caller provided a value // Add `&` automatically. // TODO: same logic in call_args() if !is_range_slice { - if !node.left.is_lvalue() { + if !receiver_expr_is_addressable { if node.left.is_as_cast() { g.inside_smartcast = true if node.left is ast.SelectorExpr && !left_type.is_ptr() { diff --git a/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.c.must_have b/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.c.must_have new file mode 100644 index 000000000..ff12da643 --- /dev/null +++ b/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.c.must_have @@ -0,0 +1 @@ +builtin__u8_vstring(ADDR(u8, builtin__string_at(msg, 0))) diff --git a/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.vv b/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.vv new file mode 100644 index 000000000..ccb09acf7 --- /dev/null +++ b/vlib/v/gen/c/testdata/string_index_method_ptr_receiver.vv @@ -0,0 +1,8 @@ +fn read_char() string { + msg := 'foo' + return unsafe { msg[0].vstring() } +} + +fn main() { + _ := read_char() +} -- 2.39.5