From d3aa7700c7db2149fd9376e20bb6814f9a9fab4e Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 9 Aug 2022 17:44:19 +0800 Subject: [PATCH] cgen: fix shared struct method call (#15386) --- vlib/v/gen/c/fn.v | 9 ++++-- vlib/v/tests/shared_struct_method_call_test.v | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/shared_struct_method_call_test.v diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 2d019937eb..dc72acb5db 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -999,6 +999,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { g.write('${name}(') } } + is_node_name_in_first_last_repeat := node.name in ['first', 'last', 'repeat'] if node.receiver_type.is_ptr() && (!left_type.is_ptr() || left_type.has_flag(.variadic) || node.from_embed_types.len != 0 || (left_type.has_flag(.shared_f) && node.name != 'str')) { @@ -1009,7 +1010,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { if !node.left.is_lvalue() { g.write('ADDR($rec_cc_type, ') has_cast = true - } else if node.name !in ['first', 'last', 'repeat'] { + } else if !is_node_name_in_first_last_repeat && !(left_type.has_flag(.shared_f) + && left_type == node.receiver_type) { g.write('&') } } @@ -1036,7 +1038,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { g.write('/*af receiver arg*/' + arg_name) } else { if left_sym.kind == .array && node.left.is_auto_deref_var() - && node.name in ['first', 'last', 'repeat'] { + && is_node_name_in_first_last_repeat { g.write('*') } if node.left is ast.MapInit { @@ -1061,7 +1063,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } g.write(embed_name) } - if left_type.has_flag(.shared_f) { + if left_type.has_flag(.shared_f) + && (left_type != node.receiver_type || is_node_name_in_first_last_repeat) { g.write('->val') } } diff --git a/vlib/v/tests/shared_struct_method_call_test.v b/vlib/v/tests/shared_struct_method_call_test.v new file mode 100644 index 0000000000..516c524abe --- /dev/null +++ b/vlib/v/tests/shared_struct_method_call_test.v @@ -0,0 +1,28 @@ +module main + +struct Aa { +mut: + b []int +} + +fn append_ok(shared a Aa, new_b int) { + lock a { + a.b << new_b + } +} + +fn (shared a Aa) append_fails(new_b int) { + lock a { + a.b << new_b + } +} + +fn test_shared_struct_method_call() { + shared a := Aa{} + append_ok(shared a, 1) + a.append_fails(2) + rlock a { + println(a.b) + assert a.b == [1, 2] + } +}