From 563987c450f8e5341a0c999dcdd2ce172c577f93 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 17 Sep 2025 13:22:50 +0300 Subject: [PATCH] cgen: restore old behaviour for `struct Name{field &C.FILE};i:=Name{};unsafe{i.free()}` (fix #25325) (#25327) --- vlib/v/gen/c/auto_free_methods.v | 8 ++++++-- .../testdata/free_for_struct_with_c_fields.c.must_have | 5 +++++ .../v/gen/c/testdata/free_for_struct_with_c_fields.out | 3 +++ vlib/v/gen/c/testdata/free_for_struct_with_c_fields.vv | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 vlib/v/gen/c/testdata/free_for_struct_with_c_fields.c.must_have create mode 100644 vlib/v/gen/c/testdata/free_for_struct_with_c_fields.out create mode 100644 vlib/v/gen/c/testdata/free_for_struct_with_c_fields.vv diff --git a/vlib/v/gen/c/auto_free_methods.v b/vlib/v/gen/c/auto_free_methods.v index 5497b29efc..b34d0b2a41 100644 --- a/vlib/v/gen/c/auto_free_methods.v +++ b/vlib/v/gen/c/auto_free_methods.v @@ -62,7 +62,7 @@ fn (mut g Gen) gen_free_method(typ ast.Type) string { match mut sym.info { ast.Struct { - g.gen_free_for_struct(objtyp, sym.info, styp, fn_name) + g.gen_free_for_struct(objtyp, sym.info, styp, fn_name, sym.is_builtin()) } ast.Array { g.gen_free_for_array(sym.info, styp, fn_name) @@ -105,7 +105,11 @@ fn (mut g Gen) gen_free_for_interface(sym ast.TypeSymbol, info ast.Interface, st fn_builder.writeln('}') } -fn (mut g Gen) gen_free_for_struct(typ ast.Type, info ast.Struct, styp string, fn_name string) { +fn (mut g Gen) gen_free_for_struct(typ ast.Type, info ast.Struct, styp string, ofn_name string, sym_is_builtin bool) { + mut fn_name := ofn_name + if sym_is_builtin { + fn_name = 'builtin__${fn_name}' + } g.definitions.writeln('${g.static_non_parallel}void ${fn_name}(${styp}* it);') mut fn_builder := strings.new_builder(128) defer { diff --git a/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.c.must_have b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.c.must_have new file mode 100644 index 0000000000..6ab96362c5 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.c.must_have @@ -0,0 +1,5 @@ +static void main__Abc_free(main__Abc* it); +static void builtin__FILE_free(FILE* it); +static void builtin__FILE_free(FILE* it) { +static void main__Abc_free(main__Abc* it) { +builtin__FILE_free(&(it->myfile)); diff --git a/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.out b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.out new file mode 100644 index 0000000000..f983207b12 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.out @@ -0,0 +1,3 @@ +Abc{ + myfile: &nil +} diff --git a/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.vv b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.vv new file mode 100644 index 0000000000..bf30d08982 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_for_struct_with_c_fields.vv @@ -0,0 +1,10 @@ +struct Abc { + myfile &C.FILE = unsafe { nil } +} + +@[manualfree] +fn main() { + a := Abc{} + println(a) + unsafe { a.free() } +}