From c10f5639b29f29b8cf3ec1c3d8bb1dc378c06f37 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 25 Mar 2026 23:00:53 +0300 Subject: [PATCH] cgen: fix bad function argument name causes compilation error (fixes #26746) --- vlib/v/gen/c/cgen.v | 25 +++++++++++----- .../v/tests/debugger_reserved_arg_name_test.v | 29 +++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 vlib/v/tests/debugger_reserved_arg_name_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index cdcc5d52b..78b0fb7d9 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5048,6 +5048,14 @@ fn (mut g Gen) check_var_scope(obj ast.Var, node_pos int) bool { return true } +@[inline] +fn (g &Gen) debugger_var_cname(obj ast.Var) string { + if obj.is_inherited { + return '${closure_ctx}->${c_name(obj.name)}' + } + return c_name(obj.name) +} + // debugger_stmt writes the call to V debugger REPL fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) { paline, pafile, pamod, pafn := g.panic_debug_info(node.pos) @@ -5072,6 +5080,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) { continue } if obj is ast.Var && g.check_var_scope(obj, node.pos.pos) { + cobj_name := g.debugger_var_cname(obj) keys.write_string('_S("${obj.name}")') var_typ := if obj.ct_type_var != .no_comptime { g.type_resolver.get_type(ast.Ident{ obj: obj }) @@ -5122,24 +5131,24 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) { if obj.ct_type_var == .smartcast { cur_variant_sym := g.table.sym(g.unwrap_generic(g.type_resolver.get_ct_type_or_default('${g.comptime.comptime_for_variant_var}.typ', ast.void_type))) - param_var.write_string('${obj.name}${dot}_${cur_variant_sym.cname}') + param_var.write_string('${cobj_name}${dot}_${cur_variant_sym.cname}') } else if cast_sym.info is ast.Aggregate { sym := g.table.sym(cast_sym.info.types[g.aggregate_type_idx]) func = g.get_str_fn(cast_sym.info.types[g.aggregate_type_idx]) - param_var.write_string('${obj.name}${dot}_${sym.cname}') + param_var.write_string('${cobj_name}${dot}_${sym.cname}') } else if obj_sym.kind == .interface && cast_sym.kind == .interface { ptr := '*'.repeat(obj.typ.nr_muls()) - param_var.write_string('I_${obj_sym.cname}_as_I_${cast_sym.cname}(${ptr}${obj.name})') + param_var.write_string('I_${obj_sym.cname}_as_I_${cast_sym.cname}(${ptr}${cobj_name})') } else if obj_sym.kind in [.sum_type, .interface] { - param_var.write_string('${obj.name}') + param_var.write_string('${cobj_name}') if opt_cast { param_var.write_string('.data)') } param_var.write_string('${dot}_${cast_sym.cname}') } else if is_option && !var_typ_is_option { - param_var.write_string('${obj.name}.data') + param_var.write_string('${cobj_name}.data') } else { - param_var.write_string('${obj.name}') + param_var.write_string('${cobj_name}') } param_var.write_string(')') @@ -5149,7 +5158,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) { if is_option && !var_typ_is_option { // option unwrap base_typ := g.base_type(obj.typ) - values.write_string('${func}(*(${base_typ}*)${obj.name}.data)}') + values.write_string('${func}(*(${base_typ}*)${cobj_name}.data)}') } else { _, str_method_expects_ptr, _ := cast_sym.str_method_info() @@ -5175,7 +5184,7 @@ fn (mut g Gen) debugger_stmt(node ast.DebuggerStmt) { } else { '' } - values.write_string('${func}(${deref}${obj.name})}') + values.write_string('${func}(${deref}${cobj_name})}') } } vars << obj.name diff --git a/vlib/v/tests/debugger_reserved_arg_name_test.v b/vlib/v/tests/debugger_reserved_arg_name_test.v new file mode 100644 index 000000000..00ee70ed9 --- /dev/null +++ b/vlib/v/tests/debugger_reserved_arg_name_test.v @@ -0,0 +1,29 @@ +import os + +fn test_dbg_compiles_with_reserved_function_argument_name() { + pid := os.getpid() + source_path := os.join_path(os.vtmp_dir(), 'v_issue_26746_debugger_reserved_arg_name_${pid}.v') + exe_path := os.join_path(os.vtmp_dir(), 'v_issue_26746_debugger_reserved_arg_name_${pid}.exe') + source := [ + 'pub fn bad_function(array []u8) u8 {', + r' $dbg', + ' return array[0]', + '}', + '', + 'fn main() {', + ' _ = bad_function([u8(1)])', + '}', + ].join_lines() + os.write_file(source_path, source)! + defer { + os.rm(source_path) or {} + os.rm(exe_path) or {} + } + cmd := '${os.quoted_path(@VEXE)} -o ${os.quoted_path(exe_path)} ${os.quoted_path(source_path)}' + res := os.execute(cmd) + if res.exit_code != 0 { + eprintln('> failed command: ${cmd}') + eprintln(res.output) + } + assert res.exit_code == 0 +} -- 2.39.5