cgen: make sure to call the overriden pub fn (mut a []string) free() { method, NOT the generic fn (a &array) free() { one. (#23911)

This commit is contained in:
Delyan Angelov 2025-03-11 21:09:55 +02:00 committed by GitHub
parent 2dc0911e8c
commit 5439ff9cde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 43 additions and 2 deletions

View File

@ -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}'
}

View File

@ -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);

View File

@ -0,0 +1 @@
start,42

View File

@ -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()
}