From c0c07db7ccc5448b067d1b2721633c49b7c890c1 Mon Sep 17 00:00:00 2001 From: crthpl <56052645+crthpl@users.noreply.github.com> Date: Wed, 2 Feb 2022 00:55:57 -0800 Subject: [PATCH] cgen: fix struct field init from shared struct field (#13343) --- vlib/v/gen/c/cgen.v | 17 ++++++++------- vlib/v/tests/struct_shared_field_init_test.v | 22 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 vlib/v/tests/struct_shared_field_init_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 82182f53e1..42fde59c49 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2471,10 +2471,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ } // Generic dereferencing logic neither_void := ast.voidptr_type !in [got_type, expected_type] - to_shared := expected_type.has_flag(.shared_f) && !got_type_raw.has_flag(.shared_f) - && !expected_type.has_flag(.optional) - // from_shared := got_type_raw.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) - if to_shared { + if expected_type.has_flag(.shared_f) && !got_type_raw.has_flag(.shared_f) + && !expected_type.has_flag(.optional) { shared_styp := exp_styp[0..exp_styp.len - 1] // `shared` implies ptr, so eat one `*` if got_type_raw.is_ptr() { g.error('cannot convert reference to `shared`', expr.pos()) @@ -2492,6 +2490,13 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ g.is_shared = old_is_shared g.writeln('}, sizeof($shared_styp))') return + } else if got_type_raw.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) { + if expected_type.is_ptr() { + g.write('&') + } + g.expr(expr) + g.write('->val') + return } if got_is_ptr && !expected_is_ptr && neither_void && exp_sym.kind != .placeholder && expr !is ast.InfixExpr { @@ -6315,10 +6320,6 @@ fn (mut g Gen) size_of(node ast.SizeOf) { g.write('sizeof(${util.no_dots(styp)})') } -fn (g &Gen) is_importing_os() bool { - return 'os' in g.table.imports -} - fn (mut g Gen) go_expr(node ast.GoExpr) { line := g.go_before_stmt(0) mut handle := '' diff --git a/vlib/v/tests/struct_shared_field_init_test.v b/vlib/v/tests/struct_shared_field_init_test.v new file mode 100644 index 0000000000..4a09731fb8 --- /dev/null +++ b/vlib/v/tests/struct_shared_field_init_test.v @@ -0,0 +1,22 @@ +struct AA { + b shared BB +} + +struct BB { + a &int +} + +struct CC { + a BB +} + +fn test_struct_shared_field_init() { + a := 3 + table := &AA{ + b: BB{&a} + } + c := CC{ + a: table.b + } + assert *c.a.a == 3 +}