diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index f09aaf2c5d..6ab0578dff 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1477,7 +1477,7 @@ fn (mut g Gen) resolve_receiver_name(node ast.CallExpr, unwrapped_rec_type ast.T receiver_type_name = 'map' } if final_left_sym.kind == .array && !(left_sym.kind == .alias && left_sym.has_method(node.name)) - && node.name in ['clear', 'repeat', 'sort_with_compare', 'sorted_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] { + && node.name in ['clear', 'repeat', 'sort_with_compare', 'sorted_with_compare', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] { if !(left_sym.info is ast.Alias && typ_sym.has_method(node.name)) { // `array_Xyz_clone` => `array_clone` receiver_type_name = 'array' @@ -1658,7 +1658,13 @@ fn (mut g Gen) method_call(node ast.CallExpr) { receiver_type_name = g.resolve_receiver_name(node, unwrapped_rec_type, final_left_sym, left_sym, typ_sym) - mut name := util.no_dots('${receiver_type_name}_${node.name}') + mut name := '' + if is_free_method { + free_method_name := g.get_free_method(unwrapped_rec_type) + name = free_method_name + } else { + name = util.no_dots('${receiver_type_name}_${node.name}') + } if left_sym.kind == .chan && node.name in ['close', 'try_pop', 'try_push'] { name = 'sync__Channel_${node.name}' } diff --git a/vlib/v/gen/c/testdata/free_array_of_strings.c.must_have b/vlib/v/gen/c/testdata/free_array_of_strings.c.must_have new file mode 100644 index 0000000000..e4f078fc95 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_array_of_strings.c.must_have @@ -0,0 +1,2 @@ +Array_string my_array_of_strings = __new_array_with_default(0, 10, sizeof(string), 0); +Array_string_free(&my_array_of_strings); diff --git a/vlib/v/gen/c/testdata/free_array_of_strings.out b/vlib/v/gen/c/testdata/free_array_of_strings.out new file mode 100644 index 0000000000..1a5dc315c6 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_array_of_strings.out @@ -0,0 +1 @@ +start,42 diff --git a/vlib/v/gen/c/testdata/free_array_of_strings.vv b/vlib/v/gen/c/testdata/free_array_of_strings.vv new file mode 100644 index 0000000000..e92e712982 --- /dev/null +++ b/vlib/v/gen/c/testdata/free_array_of_strings.vv @@ -0,0 +1,32 @@ +fn ii() int { + return 42 +} + +fn ss() string { + return ii().str() +} + +@[manualfree] +fn ffff() { + mut my_array_of_strings := []string{cap: 10} + my_array_of_strings << 'start' + mystring := ss() + if mystring.len > 0 { + my_array_of_strings << mystring + } + sa := my_array_of_strings.join(',') + println(sa) + unsafe { + sa.free() + mystring.free() + // The following SHOULD NOT generate the general `array_free(&my_array_of_strings);` . + // Instead, it SHOULD generate the more specific `Array_string_free(&my_array_of_strings);` ! + // That more specific version, makes sure, that all the element strings are freed, + // before the array itself is also freed. + my_array_of_strings.free() + } +} + +fn main() { + ffff() +}